SYSTEM CALL: semop(); PROTOTYPE: int semop ( int semid, struct sembuf *sops, unsigned nsops); RETURNS: 0 on success (all operations performed) -1 on error: errno = E2BIG (nsops greater than max number of ops allowed atomically) EACCESS (permission denied) EAGAIN (IPC_NOWAIT asserted, operation could not go through) EFAULT (invalid address pointed to by sops argument) EIDRM (semaphore set was removed) EINTR (Signal received while sleeping) EINVAL (set doesn't exist, or semid is invalid) ENOMEM (SEM_UNDO asserted, not enough memory to create the undo structure necessary) ERANGE (semaphore value out of range) NOTES:
`sops`sops参数指向 `sembuf` 类型的数组。sembuf。此结构在linux/sem.h中声明如下
/* semop system call takes an array of these */ struct sembuf { ushort sem_num; /* semaphore index in array */ short sem_op; /* semaphore operation */ short sem_flg; /* operation flags */ };
您希望处理的信号量编号
要执行的操作(正数、负数或零)
操作标志
如果 `sem_op`sem_op为负数,则其值将从信号量中减去。这与获取信号量控制或监视访问的资源相关。如果未指定 IPC_NOWAIT,则调用进程将休眠,直到信号量中可用的资源量达到请求的数量(另一个进程已释放了一些资源)。
如果 `sem_op`sem_op如果 `sem_op` 为正数,则其值将添加到信号量中。这与将资源返回到应用程序的信号量集相关。当不再需要资源时,应始终将资源返回到信号量集!
最后,如果 `sem_op`sem_op为零 (0),则调用进程将 sleep(),直到信号量的值为 0。这与等待信号量达到 100% 利用率相关。一个很好的例子是具有超级用户权限的守护进程,如果信号量集达到完全利用率,它可以动态调整信号量集的大小。
为了解释 `semop`semop调用,让我们回顾一下我们的打印室场景。假设只有一台打印机,一次只能处理一个作业。我们创建一个信号量集,其中只有一个信号量(只有一台打印机),并将该信号量初始化为值 1(一次只能处理一个作业)。
每次我们想要向这台打印机发送作业时,我们需要首先确保资源可用。我们通过尝试从信号量中获取一个单元来做到这一点。让我们加载一个 sembuf 数组来执行操作
struct sembuf sem_lock = { 0, -1, IPC_NOWAIT };
if((semop(sid, &sem_lock, 1) == -1) perror("semop");
当我们的打印作业完成后,我们必须将资源返回到信号量集,以便其他人可以使用打印机。
struct sembuf sem_unlock = { 0, 1, IPC_NOWAIT };