se拖把和 semtimedop 子例程

用途

执行信号操作。

标准 C 库 (libc.a)

语法

#include <sys/sem.h>
int semop (SemaphoreIDSemaphoreOperations, NumberOfSemaphoreOperations)
int  SemaphoreID;
struct sembuf * SemaphoreOperations;
size_t  NumberOfSemaphoreOperations;
#include <sys/sem.h>
int semtimedop (SemaphoreIDSemaphoreOperations,
NumberOfSemaphoreOperations, Timeout)
int  SemaphoreID;
struct sembuf * SemaphoreOperations;
size_t  NumberOfSemaphoreOperations;

struct timespec * timeout;

描述

se拖把semtimedop 子例程对与 SemaphoreID 参数指定的信号量标识相关联的信号量集执行操作。

semtimedop 子例程限制调用者在等待信号操作完成时将休眠的时间。 timespec 结构在 /usr/include/sys/time.h 文件中定义,并包含以下字段:

描述
tv_sec 计时器上的秒数
tv_nsec 计时器上的纳秒

如果调用者在完成操作之前休眠了 timespec 结构分配的时间,那么当前操作将异常中止,并且 semtimedop 子例程将返回错误。

注: semtimedop子程序从AIX®Version6.1 开始提供。

sembuf 结构在 usr/include/sys/sem.h 文件中定义。 由 SemaphoreOperations 参数指定的每个 sembuf 结构都包含以下字段:

描述
sem_num 信号量编号
sem_op 信号操作
sem_flg 操作标志

指定的每个信号量操作sem_op在由 SemaphoreID 参数和sem_num:NONE. 信号量操作按它们在 sembuf 数组中接收的顺序执行。 该sem_op字段指定三个信号量操作中的一个。

  1. 如果sem_op字段为负整数,并且调用进程具有变更许可权,那么将发生下列其中一种情况:
    • 如果 semval 变量 (请参阅 /usr/include/sys/sem.h 文件) 大于或等于sem_op字段,绝对值sem_opsemval 变量中减去字段。 此外,如果 SEM_UNDO 标志在sem_flg字段,绝对值sem_op字段将添加到指定信号量的调用进程的 semadj 值。
    • 如果 semval 变量小于sem_op字段中设置了 IPC_NOWAIT 值。sem_flg字段,立即返回 se拖把semtimedop 子例程。
    • 如果 semval 变量小于sem_op字段和 IPC_NOWAIT 值未在sem_flg字段, se拖把semtimedop 子例程将增大semncnt与指定的信号量相关联的字段,并暂挂调用进程,直到出现下列其中一种情况为止:
      • semval 变量的值变得大于或等于sem_op:NONE. 值semncnt然后对与指定的信号量相关联的字段进行递减,并且该字段的绝对值为sem_opsemval 变量中减去字段。 此外,如果 SEM_UNDO 标志在sem_flg字段,绝对值sem_op字段将添加到指定信号量的调用进程的 semadj 值。
      • 将从系统中除去调用进程正在等待操作的 SemaphoreID 参数。 当出现这种情况时,errno全局变量将被设置为EIDRM标志,并返回-1的值。
      • 调用进程接收到要捕获的信号。 当发生此情况时, se拖把semtimedop 子例程将减小semncnt与指定的信号量关联的字段。 当semzcnt字段已递减,调用进程将按 sigaction (sigaction , sigvec 或 signal 子例程) 子例程的规定恢复。
      • 调用进程在 timespec 结构分配的时间内休眠。 出现这种情况时,全局变量errno将被设置为ETIMEDOUT标志,并返回-1值。
  2. 如果sem_op字段是正整数,调用进程具有 alter permission ,sem_op将字段添加到 semval 变量。 此外,如果 SEM_UNDO 标志在sem_flg字段,值sem_op将从指定信号量的调用进程的 semadj 值中减去字段。
  3. 如果sem_op字段为 0 ,并且调用进程具有读许可权,发生下列其中一种情况:
    • 如果 semval 变量是 0 ,那么 se拖把semtimedop 子例程会立即返回。
    • 如果 semval 变量不等于 0 ,并且 IPC_NOWAIT 值在sem_flg字段,立即返回 se拖把semtimedop 子例程。
    • 如果 semval 变量不等于 0 且 IPC_NOWAIT 值未在sem_flg字段, se拖把semtimedop 子例程将增加semzcnt与指定的信号量相关联的字段,并暂挂调用进程的执行,直到发生下列其中一个情况为止:
      • semval 变量的值变为 0。 发生此情况时,semzcnt与指定的信号量相关联的字段将递减。
      • 将从系统中除去调用进程正在等待操作的 SemaphoreID 参数。 如果出现这种情况,errno全局变量将被设置为EIDRM错误代码,并返回-1值。
      • 调用进程接收到要捕获的信号。 发生此情况时, se拖布semtimedop 子例程将减小semzcnt与指定的信号量关联的字段。 当semzcnt字段已递减,调用进程将按照 sigaction 子例程的规定恢复执行。
      • 调用进程在 timespec 结构分配的时间内休眠。 出现这种情况时,全局变量errno将被设置为ETIMEDOUT标志,并返回-1值。

有关信号量限制的信息,请参阅: 进程间通信限制

注: 使用无效的 Timeout 参数调用 semtimedop 子例程将防止在必要时暂挂调用进程。 如果为semtimedop子例程指定的超时参数无效,并且需要暂停调用进程,那么将设置errno全局变量来指示错误,并返回值-1。

参数

描述
SemaphoreID 指定信号量标识。
NumberOfSemaphoreOperations 指定数组中的结构数。
SemaphoreOperations 指向结构的数组,每个结构指定一个信号操作。
超时 指向用于指定操作不应休眠的时间间隔的结构。

返回值

成功完成后, se拖把semtimedop 子例程将返回值 0。 此外,将操作的每个信号量的 SemaphoreID 参数值设置为调用进程的进程标识。

如果semopsemtimedop子程序不成功,则返回值为-1,并设置errno全局变量来指示错误。 如果 SEM_ORDER 标志是在sem_flgSemaphoreOperations 数组中第一个信号量操作的字段, SEM_ERR 值在sem_flg操作失败的字段。

如果调用进程正在等待处理的SemaphoreID参数已从系统中删除,则Erno全局变量将被设置为EIDRM错误代码,并返回-1值。

错误代码

如果对于 SemaphoreOperations 参数指定的任何信号量操作,下列其中一项或多项为真,那么 se拖把semtimedop 子例程将失败。 如果操作是单独执行的,那么 SEM_ORDER 标志的讨论将提供有关错误情况的更多信息。

描述
EINVAL SemaphoreID 参数不是有效的信号量标识。
EINVAL 调用进程请求 SEM_UNDO 标志将超过限制的单个信号量的数量。
EINVAL Timeout 参数指定了小于 0 的 tv_sectv_nsec 值,或者指定了大于 1000 万的 tv_nsec 值。
EFBIG sem_num值小于 0 或大于或等于与 SemaphoreID 参数关联的集合中的信号数。
E2BIG NumberOfSemaphoreOperations参数大于系统规定的最大值。
EACCES 拒绝调用进程对指定操作的许可权。
再次 该操作将导致暂挂调用进程,但 IPC_NOWAIT 值是在sem_flg:NONE.
ENOMEM 内存不足,无法执行必需的操作。
ENOSPC 将超过对请求 SEM_UNDO 标志的单个进程数的限制。
EINVAL 调用进程请求 SEM_UNDO 标志将超过限制的单个信号量的数量。
ERANGE 操作将导致 semval 值溢出系统施加的限制。
ERANGE 操作将导致 semadj 值溢出系统施加的限制。
Efault SemaphoreOperations 参数指向进程的地址空间外部。
EINTR 信号中断了 se拖把 子例程。
EIDRM 已从系统中除去信号量标识 SemaphoreID 参数。
Efault Timeout 参数指向无效地址。
ETIMEDOUT Timeout 参数指定的时间在可以完成所请求的操作之前到期。