`
tempsitegoogle
  • 浏览: 866578 次
文章分类
社区版块
存档分类
最新评论

使用System V信号量实现多线程互斥

 
阅读更多

POSIX Thread中提供了非常强大的线程互斥机制, 如 pthread_mutex_XXXX / pthread_cond_XXXX 以及semaphore(sem_wait/sem_post)等。在同一进程内的多线程编程非常方便灵活。但对于跨进程的线程互斥问题就变得麻烦了。

其实主流的Linux在内核中也实现了System V的IPC, 在跨进程的线程互斥方面实现起来更加简单。当然,同一进程容器内的多线程也可以使用。

信号量的创建

semget的man page:http://linux.die.net/man/2/semget

如果是在同一进程或者亲缘进程内使用


这样就创建了一个无名信号量集合,其中semget的第2个参数表示这个信号量集合中有1个信号量。

而对于非亲缘关系的多进程内线程使用的信号量,则一般这样创建

ftok函数用于创建System V 的 IPC key, 其中第一个参数必须是存在的文件路径且具备可访问权限。
第2个参数(proj_id)必须是大于0的数,且这个数只有低8位起作用。
ftok通过计算指定文件的索引节点的index和第2个参数proj_id,来创建一个唯一的IPC key.
例如, /tmp/foo对应的文件索引号是0x100000, 那么proj_id等于42(0x2A), 那么得到的key就是 0x2A100000
也就是说,对于不同的进程,只要ftok的2个参数相同,则得到的IPC key的值也会是相同的。

而对于同一个IPC key, semget保证在不同的进程中能够或得到相同的信号量集合.
而这个信号量集合是一个内核数据结构,不会因为进程的退出而自动销毁,所以需要程序显式地进行销毁。


信号量的销毁

semctl的man page: http://linux.die.net/man/2/semctl

信号量的使用

信号量的使用主要是通过这2个函数,man page(http://linux.die.net/man/2/semop)

首先了解一下sembuf 的结构

  • sem_num : 表面当前操作的是信号量集合中的第几个信号量,0表示第一个
  • sem_op : 操作数,见下文
  • sem_flg :IPC_NOWAIT标志表示此操作仅做测试,进阻塞当前线程;SEM_UNDO标志表示进程提前退出时撤销此操作

对于sem_op,分为下列几种情况

  • 如果 sem_op 为 0,则测试 sem_num指定的信号量, 以确定它是否为 0。如果 sem_num指定的信号量 为 0,则运行下一个测试。如果 sem_num 不为 0,则在未设置 IPC_NOWAIT 时,操作将阻塞直至信号量变为 0,而在设置了 IPC_NOWAIT 时,则跳过其他测试直接返回。
  • 如果 sem_op 是某个正数,则将信号量的值加上 sem_op 的值, 此操作永远都不会阻塞。
  • 如果 sem_op 是一个负整数,并且 sem_num指定的信号量 的值大于或等于 sem_op 的绝对值,则从信号量的值减去该绝对值。
  • 如果 sem_op 是一个负整数,并且 sem_num指定的信号量 的值小于 sem_op 的绝对值,则在 IPC_NOWAIT 标志设置的情况下立即停止测试的执行,而如果IPC_NOWAIT 标志没有设置则阻塞,直至信号量的值变得大于 sem_op 的绝对值

下面看2个具体的实例方便理解

1. 将信号量作为临界区使用,保证某段代码在同一时间内只能有一个线程进入执行

2. 将信号量作为可用资源数标识

这是一种很常见的情况,在生产者-消费者线程池模型中, 一组生产者线程从网络或者文件中读取到数据包并追加到工作任务队列;另一组消费者线程从工作任务队列中获取工作任务后执行。

在这种模式下,这些消费者线程需要根据工作任务队列中是否有需要处理的工作任务来及时地启动或者等待执行。

首先对于生产者线程, 当将数据包追加到工作任务队列后,可以将可用资源数增一,此操作永远都不会阻塞

其次对于消费者线程

分享到:
评论

相关推荐

    Linux c语言多线程实现生产者/消费者问题

    以生产者/消费者问题为例来阐述Linux线程的控制和通信。一组生产者线程与一组消费者线程通过缓冲区发生联系。生产者线程将生产的产品送入缓冲区,消费者线程则从中取出产品。缓冲区有N 个,是一个环形的缓冲池。 ...

    2018年C++教程网的linux网络编程视频共41集百度云下载链接.rar

    33System V共享内存与信号量综合 用信号量解决生产者消费者问题 实现shmfifo 34POSIX消息队列 POSIX消息队列相关函数 POSIX消息队列示例 35POSIX共享内存 POSIX共享内存相关函数 POSIX共享内存示例 Linux网络编程之...

    linux网络编程

    信号量集函数 信号量示例 31System V信号量(二) 用信号量实现进程互斥示例 32System V信号量(三) 用信号集解决哲学家就餐问题 33System V共享内存与信号量综合 用信号量解决生产者消费者问题 实现shmfifo 34...

    [SystemView] SystemView升级至V3.07,重大更新,免费使用所有特性(非商业)

    [SystemView] SystemView升级至V3.07,重大更新,免费使用所有特性(非商业)SystemView是一个可以在线调试嵌入式系统的工具,它可以分析有哪些中断、任务执行了,以及这些中断、任务执行的先后关系。还可以查看一些...

    C++教程网《Linux网络编程》视频百度云地址

    33System V共享内存与信号量综合 用信号量解决生产者消费者问题 实现shmfifo 34POSIX消息队列 POSIX消息队列相关函数 POSIX消息队列示例 35POSIX共享内存 POSIX共享内存相关函数 POSIX共享内存示例 Linux...

    Linux网络编程 视频 教程

    33System V共享内存与信号量综合 用信号量解决生产者消费者问题 实现shmfifo 34POSIX消息队列 POSIX消息队列相关函数 POSIX消息队列示例 35POSIX共享内存 POSIX共享内存相关函数 POSIX共享内存示例 Linux...

    C++教程网视频:linux网络编程

    33System V共享内存与信号量综合 用信号量解决生产者消费者问题 实现shmfifo 34POSIX消息队列 POSIX消息队列相关函数 POSIX消息队列示例 35POSIX共享内存 POSIX共享内存相关函数 POSIX共享内存示例 Linux...

    c++教程网的linux网络编程视频下载

    33System V共享内存与信号量综合 用信号量解决生产者消费者问题 实现shmfifo 34POSIX消息队列 POSIX消息队列相关函数 POSIX消息队列示例 35POSIX共享内存 POSIX共享内存相关函数 POSIX共享内存示例 Linux...

    [免费]2018年C++教程网的linux网络编程视频百度云下载链接.rar

    33System V共享内存与信号量综合 用信号量解决生产者消费者问题 实现shmfifo 34POSIX消息队列 POSIX消息队列相关函数 POSIX消息队列示例 35POSIX共享内存 POSIX共享内存相关函数 POSIX共享内存示例 Linux...

    UNIX网络编程 卷2:进程间通信

     10.16 使用System V信号量实现Posix信号量 218  10.17 小结 224  习题 225  第11章 System V 信号量 226  11.1 概述 226  11.2 semget函数 227  11.3 semop函数 229  11.4 semctl函数 231  11.5 简单的...

    UNIX网络编程 卷2 进程间通信 带完整书签,完整目录

    10.16 使用System V信号量实现Posix信号量 218 10.17 小结 224 习题 225 第11章 System V信号量 226 11.1 概述 226 11.2 semget函数 227 11.3 semop函数 229 11.4 semctl函数 231 11.5 简单的程序 232 ...

    《UNIX网络编程 第2版. 第2卷, 进程间通信(中文版)》(W·Richard Stevens[美] 著)

    10.16 使用System V信号量实现Posix信号量 218 10.17 小结 224 习题 225 第11章 System V 信号量 226 11.1 概述 226 11.2 semget函数 227 11.3 semop函数 229 11.4 semctl函数 231 11.5 简单的程序 232 11.6 文件上...

    UNIX网络编程 第2卷 进程间通信

    10.16 使用System V信号量实现Posix信号量 218 10.17 小结 224 习题 225 第11章 System V 信号量 226 11.1 概述 226 11.2 semget函数 227 11.3 semop函数 229 11.4 semctl函数 231 11.5 简单的程序 232 11.6 文件上...

    Visual C 程序开发范例宝典第6章

    第6章 操作系统与Windows相关程序  6.1 启动相关设置  ... cc实例189 用信号量实现线程同步  cc实例190 多线程cc实例  6.8 鼠标.c键盘相关设置  cc实例191 动画鼠标  cc实例192 限制鼠标移动区域 

    Visual C++程序开发范例宝典 - 第6章

    实例243 用信号量实现线程同步 实例244 多线程实例 6.8 鼠标、键盘相关 实例245 动画鼠标 实例246 限制鼠标移动区域 实例247 鼠标穿透窗体 实例248 设置鼠标形状 实例249 控制键盘指示灯 6.9 动态链接库 实例250 ...

    SystemView 应用笔记

    还可以查看一些内核对象持有和释放的时间点,比如信号量、互斥量、事件、消息队列等。这在开发和处理具有多个线程和事件的复杂系统时尤其有效。 说白了就是我们可以通过这个软件实时监控我们实时系统的任务切换及...

    SystemView_V310_Windows_x86.exe

    SystemView 是一个可以在线调试嵌入式系统的工具,它可以分析有哪些...还可以查看一些内核对象持有和释放的时间点,比如信号量、互斥量、事件、消息队列等。这在开发和处理具有多个线程和事件的复杂系统时尤其有效。

    UNIX 高级教程系统技术内幕

    6.3.2 信号量 6.3.3 消息队列 6.3.4 共享内存 6.3.5 讨论 6.4 Mach IPC 6.4.1 基本概念 6.5 消息 6.5.1 消息的数据结构 6.5.2 消息传递接口 6.6 端口 6.6.1 端口名字空间 6.6.2 端口数据结构 6.6.3 端口变换 6.7 ...

    FreeBSD操作系统设计与实现

    11.8.1 信号量 11.8.2 消息队列 11.8.3 共享内存 11.9 复习题 11.10 参考文献 第12章 网络通信 12.1 内部结构 12.1.1 数据流 12.1.2 通信协议 12.1.3 网络接口 12.2 套接口到协议的接口 12.2.1 协议的用户请求例程 ...

Global site tag (gtag.js) - Google Analytics