Linux信号量(2)-POSIX 信号量
上一章 , 讲述了SYSTEM V信号量 , 主要运行于进程之间 , 本章主要介绍POSIX信号量:有名信号量、无名信号量 。
文章插图
POSIX信号量POSIX信号量进程是3种 IPC(Inter-Process Communication) 机制之一 , 3种 IPC 机制源于 POSIX.1 的实时扩展 。 Single UNIX Specification 将3种机制(消息队列 , 信号量和共享存储)置于可选部分中 。 在 SUSv4 之前 , POSIX 信号量接口已经被包含在信号量选项中 。 在 SUSv4 中 , 这些接口被移至了基本规范 , 而消息队列和共享存储接口依然是可选的 。
POSIX 信号量接口意在解决 XSI 信号量接口的几个缺陷 。
- 相比于 XSI 接口 , POSIX 信号量接口考虑了更高性能的实现 。
- POSIX 信号量使用更简单:没有信号量集 , 在熟悉的文件系统操作后一些接口被模式化了 。 尽管没有要求一定要在文件系统中实现 , 但是一些系统的确是这么实现的 。
- POSIX 信号量在删除时表现更完美 。 回忆一下 , 当一个 XSI 信号量被删除时 , 使用这个信号量标识符的操作会失败 , 并将 errno 设置成 EIDRM 。 使用 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
- sem_wait的作用是 , 若 sem 小于 0, 则线程阻塞于信号量 sem, 直到 sem 大于 0 ;否则信号量值减1 。
- sem_trywait作用与sem_wait相同 , 只是此函数不阻塞线程 , 如果 sem 小于 0 , 直接返回一个错误(错误设置为 EAGAIN ) 。
- sem_timedwait作用也与sem_wait相同 , 第二个参数表示阻塞时间 , 如果 sem 小于 0, 则会阻塞 , 参数指定阻塞时间长度 。 abs_timeout 指向一个结构体 , 这个结构体由从 1970-01-01 00:00:00 +0000 (UTC) 开始的秒数和纳秒数构成 。
推荐阅读
- 近期浙江引来这么多重磅级“帮手”传递什么信号?
- Linux Kernel 5.10.5发布:禁用FBCON加速滚动特性
- Linux 5.11开始围绕PCI Express 6.0进行早期准备
- Fedora正在寻求协助 希望加快Linux 5.10 LTS内核测试进度
- iPhone 12信号差真实原因曝光:不是基带问题
- Linux Mint 20.1 Ulyssa稳定版已确定延期至2021年初发布
- 英特尔Xe GPU在Linux 5.11上的性能表现不错
- iPhone12 重现iPhone 7“信号门”,但库克沉默
- MIPS架构厂商日渐式微 Linux报告其漏洞遭遇困难
- 将要报废的手机会出现这三个信号,你出现了吗?