首页 > 代码库 > Linux Programmer’s Manual -- unnamed semaphore

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)

Linux Programmer’s Manual -- unnamed semaphore