Linux信号量(2)-POSIX 信号量

上一章 , 讲述了SYSTEM V信号量 , 主要运行于进程之间 , 本章主要介绍POSIX信号量:有名信号量、无名信号量 。
Linux信号量(2)-POSIX 信号量文章插图
POSIX信号量POSIX信号量进程是3种 IPC(Inter-Process Communication) 机制之一 , 3种 IPC 机制源于 POSIX.1 的实时扩展 。 Single UNIX Specification 将3种机制(消息队列 , 信号量和共享存储)置于可选部分中 。 在 SUSv4 之前 , POSIX 信号量接口已经被包含在信号量选项中 。 在 SUSv4 中 , 这些接口被移至了基本规范 , 而消息队列和共享存储接口依然是可选的 。
POSIX 信号量接口意在解决 XSI 信号量接口的几个缺陷 。

  1. 相比于 XSI 接口 , POSIX 信号量接口考虑了更高性能的实现 。
  2. POSIX 信号量使用更简单:没有信号量集 , 在熟悉的文件系统操作后一些接口被模式化了 。 尽管没有要求一定要在文件系统中实现 , 但是一些系统的确是这么实现的 。
  3. POSIX 信号量在删除时表现更完美 。 回忆一下 , 当一个 XSI 信号量被删除时 , 使用这个信号量标识符的操作会失败 , 并将 errno 设置成 EIDRM 。 使用 POSIX 信号量时 , 操作能继续正常工作直到该信号量的最后一次引用被释放 。
分类POSIX信号量是一个sem_t类型的变量 , 但POSIX有两种信号量的实现机制:无名信号量和命名信号量 。 无名信号量只可以在共享内存的情况下 , 比如实现进程中各个线程之间的互斥和同步 , 因此无名信号量也被称作基于内存的信号量;命名信号量通常用于不共享内存的情况下 , 比如进程间通信 。
同时 , 在创建信号量时 , 根据信号量取值的不同 , POSIX信号量还可以分为:
  • 二值信号量:信号量的值只有0和1 , 这和互斥量很类似 , 若资源被锁住 , 信号量的值为0 , 若资源可用 , 则信号量的值为1;
  • 计数信号量:信号量的值在0到一个大于1的限制值之间 , 该计数表示可用的资源的个数 。
区别有名信号量和无名信号量的差异在于创建和销毁的形式上 , 但是其他工作一样 。
无名信号量只能存在于内存中 , 要求使用信号量的进程必须能访问信号量所在的这一块内存 , 所以无名信号量只能应用在同一进程内的线程之间(共享进程的内存) , 或者不同进程中已经映射相同内存内容到它们的地址空间中的线程(即信号量所在内存被通信的进程共享) 。 意思是说无名信号量只能通过共享内存访问 。
相反 , 有名信号量可以通过名字访问 , 因此可以被任何知道它们名字的进程中的线程使用 。
单个进程中使用 POSIX 信号量时 , 无名信号量更简单 。 多个进程间使用 POSIX 信号量时 , 有名信号量更简单 。
联系无论是有名信号量还是无名信号量 , 都可以通过以下函数进行信号量值操作 。
wait(P)wait 为信号量值减一操作 , 总共有三个函数 , 函数原型如下:
#include int sem_wait(sem_t *sem);int sem_trywait(sem_t *sem);int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);Link with -pthread.这一句表示 gcc 编译时 , 要加 -pthread.返回值:若成功 , 返回 0 ;若出错 , 返回-1