Linux Programmer’s Manual -- unnamed semaphore
1. sem_init
名称
sem_init - 初始化一个未命名信号量概要
#include <semaphore.h>int sem_init(sem_t *sem, int pshared, unsigned int value);
链接库 -pthread
描述
sem_inti() 在sem指定的地址上初始化未命名信号量。参数value指定信号量的初始值。参数pshared表明信号是在线程间(同一进程下)共享还是在进程间共享。
如果pshared值为0,那么信号量在线程间(同一进程下)共享,其应在所有线程可见的地址空间上(例如,全局变量或者在堆上动态申请的)。
如果pshared不为0,那么信号量在进程间共享,并应放在共享内存区域(参看shm_open(3), nmap(2)以及shmget(2))。(因为通过fork(2)创建的子进程继承父进程的内存映射,它同样可以访问信号量。)任何可以访问共享内存区域的进程都可以通过sem_post(3),sem_wait(3)等函数操作信号量。
初始化一个已经初始化的信号量将导致未定义的行为。
返回值
sem_init()成功返回0;失败返回-1,并且设置errno指明错误。错误
EINVAL 参数value超过SEM_VALUE_MAX。ENOSYS 参数pshared置为非0,但系统不支持在进程间共享信号量(参看sem_overview(7))。
遵循
POSIX.1-2001注意
奇怪的是,POSIX.1-2001并没有指定成功调用sem_init()时的返回值。POSIX.1-2008纠正了这一点,指明成功返回0。参阅
sem_destroy(3),sem_post(3),sem_wait(3),sem_overview(7)2. sem_wait
名称
sem_wait,sem_timedwait,sem_trywait - 锁定信号量概要
#include <semaphore.h>int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
链接库 -pthread
glibc对于功能测试宏的要求(参看feature_test_macros(7)):
sem_timedwait(): _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
描述
sem_wait()递减(锁)由sem指向的信号量。如果信号量的值大于0,那么递减,并且函数立即返回。如果信号量当前的值为0,那么本次调用被阻塞直到它可以执行递减操作(即,信号量的值大于0),或者信号处理程序中断本次调用。sem_trywait()与sem_wait()相似,不同之处在于sem_trywati在递减操作不能立即执行时,返回一个错误(errno被设置为EAGAIN)而不是阻塞。
sem_timedwait()与sem_wait()相似,不同之处在于sem_timedwait在递减操作不能立即执行时,通过abs_timeout指定了本次调用的阻塞时间上限。Abs_timeout参数指向一个自大纪元,1970-01-01 00:00:00 +0000 (UTC)起,以秒和纳秒为单位的绝对超时时间结构体。该结构体定义如下:
strutct timespec {
time_t tv_sec; /* Seconds */
long tv_nsec; /* Nanoseconds [0 .. 999999999] */
};
如果在函数调用时间内超时时间到期,信号量并不立即锁定,sem_timedwait()执行失败并返回超时错误(errno被设置为ETIMEDOUT)。
如果该操作立即执行,那么无论abs_timeout为何值,sem_timedwait()永远都不会返回超时错误。此外,在这种情况下,没有检测abs_timedout的有效性。
返回值
所有这些函数在成功时返回0;失败时,返回-1,该信号量的值保持不变,并设置errno指明错误。错误
EINTR 函数调用被中断处理程序中断;参看signal(7)。EINVAL 参数sem不是有效的信号量。
以下的附加错误会出现在sem_trywait()调用中:
EAGAIN 在非阻塞下不能执行该操作(例如,信号量当前值为0)。
以下的附加错误会出现在sem_timedwait()调用中:
EINVAL 参数abs_timeout.tv_nsecs值小于0,或者大于等于1000百万。
ETIMEDOUT 在信号量锁定之前,调用超时。
遵循
POSIX.1-2001注意
信号处理程序总是中断阻塞调用这些函数之一,无论使用sigaction(2) SA_RESTART标志。参阅
clock_gettime(2),sem_getvalue(3),sem_post(3),sem_overview(7),time(7)3. sem_post
名称
sem_post - 释放信号量概要
#include <semaphore.h>Int sem_post(sem_t *sem);
链接库 -pthread
描述
Sem_post()递增(释放)sem指向的信号量。如果信号量的值因此变得大于0,那么其他通过sem_wait(3)调用阻塞的进程或线程将被唤醒并继续锁定信号量。返回值
Sem_post()成功返回0;失败时,返回-1,该信号量的值保持不变,并设置errno指明错误。错误
EINVAL sem不是有效的信号量。EOVERFLOW 超出信号量所允许的最大值。
遵循
POSIX.1-2001注意
sem_post()是异步信号安全的:它可以安全地在信号处理程序中调用。参阅
sem_getvalue(3),sem_wait(3),sem_overview(7)4. sem_destroy
名称
sem_destroy - 销毁未命名信号量概要
#include <semaphore.h>int sem_destroy(sem_t *sem);
链接库 -pthread
描述
sem_destroy()销毁由sem指向的未命名信号量。只有通过sem_init(3)初始化的信号量才可以通过sem_destroy()销毁。
销毁当前被其他进程或线程阻塞(sem_wait(3))的信号量会导致未定义行为。
返回值
Sem_destroy()成功返回0;失败时,返回-1,并设置errno指明错误。错误
EINVAL sem不是有效的信号量。遵循
POSIX.1-2001注意
未命名信号量应该在它所在的内存释放之前调用sem_destroy()。如果不这样做,在某些实现上可能会导致资源泄漏。参阅
sem_init(3),sem_post(3),sem_wait(3),sem_overview(7)郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。