一起talk C栗子吧(第一百回:C语言实例--使用信号量进行进程间同步与互斥一)
2016-01-14 20:53
387 查看
各位看官们,大家好,上一回中咱们说的是进程间同步与互斥的例子,这一回咱们说的例子是:使用信号量进行进程间同步与互斥。闲话休提,言归正转。让我们一起talk C栗子吧!
看官们,信号量是由著名计算机科学家迪杰斯特拉(Dijkstra)提出的一种概念,专门用来解决进程间同步与互斥。在他提出的概念中信号量是一个非负整数值.
信号量的操作只能有两种原子操作:
等待信号;
发送信号。
“什么是原子操作呢?”台下有看官在提问,原子操作就是指某个动作在运行时不能被其它动作中断,它会一直进行,直到该动作运行完成为止。比如,我们在写代码的时候,突然收到一封邮件,这时候系统会暂时中断写代码的程序vim(我用的是vim),然后让邮箱客户端发一个收到邮件的通知,然后再恢复到vim写代码的动作中。例子中使用vim写代码的动作就不是一个原子操作,只有它不能被其它动作中断时,它才是一个原子操作。接下来我们介绍对信号量的原子操作。
如果sem的值大于零,p操作会把sem的值减去1;
如果sem的值等于零,那么挂起执行p操作的进程;
如果有进程在因为等待sem而被挂起,那么唤醒等待的进程;
如果没有进程因为等待sem而被挂起,那么把sem的值加上1.
假设上面伪代码中的信号量sem值为1,进程A开始执行上面的伪代码,在进入临界区前先对信号量进行P操作,这时sem的值变为0,然后进程A执行临界区中的代码,这个时候进程B也开始执行上面的伪代码,在进入临界区前先对信号量进行P操作,这时进程A还没有离开临界区,信号量sem的值为零,进程B就会被挂起,直到进程A离开临界区执行V操作时,sem的值变为1,然后唤醒等待sem的进程B,接着进程B进入临界区并且执行临界区中的代码。
大家可以看到,通过信号量的P/V操作,可以保证在同一个时间内,只有一个进程在执行临界区中的代码,也就是说实现了进程的同步与互斥。
看官们,本章回中就不写代码了,因为我们还没有介如何使用信号量,在后面的章回中,我们会介绍信号量的操作,并且结合具体的例子,把伪代码转换成实际的代码。
各位看官,关于使用信号量进行进程间同步与互斥的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。
看官们,信号量是由著名计算机科学家迪杰斯特拉(Dijkstra)提出的一种概念,专门用来解决进程间同步与互斥。在他提出的概念中信号量是一个非负整数值.
信号量的操作只能有两种原子操作:
等待信号;
发送信号。
“什么是原子操作呢?”台下有看官在提问,原子操作就是指某个动作在运行时不能被其它动作中断,它会一直进行,直到该动作运行完成为止。比如,我们在写代码的时候,突然收到一封邮件,这时候系统会暂时中断写代码的程序vim(我用的是vim),然后让邮箱客户端发一个收到邮件的通知,然后再恢复到vim写代码的动作中。例子中使用vim写代码的动作就不是一个原子操作,只有它不能被其它动作中断时,它才是一个原子操作。接下来我们介绍对信号量的原子操作。
等待信号
等待信号也叫P操作。例P(sem)表示对信号量sem进行P操作。如果sem的值大于零,p操作会把sem的值减去1;
如果sem的值等于零,那么挂起执行p操作的进程;
发送信号
发送信号也叫V操作。例如V(sem)表示对信号量sem进行V操作。如果有进程在因为等待sem而被挂起,那么唤醒等待的进程;
如果没有进程因为等待sem而被挂起,那么把sem的值加上1.
伪代码
下面是使用信号量进行进程同步与互斥的伪代码:[code]nocritical code //非临界区的代码 P(sem); //执行P操作,进入临界区,执行临界区中的代码 { critical code; //临界区代码 do something } V(sem); //执行V操作,离开临界区 nocritical code //非临界区的代码
假设上面伪代码中的信号量sem值为1,进程A开始执行上面的伪代码,在进入临界区前先对信号量进行P操作,这时sem的值变为0,然后进程A执行临界区中的代码,这个时候进程B也开始执行上面的伪代码,在进入临界区前先对信号量进行P操作,这时进程A还没有离开临界区,信号量sem的值为零,进程B就会被挂起,直到进程A离开临界区执行V操作时,sem的值变为1,然后唤醒等待sem的进程B,接着进程B进入临界区并且执行临界区中的代码。
大家可以看到,通过信号量的P/V操作,可以保证在同一个时间内,只有一个进程在执行临界区中的代码,也就是说实现了进程的同步与互斥。
看官们,本章回中就不写代码了,因为我们还没有介如何使用信号量,在后面的章回中,我们会介绍信号量的操作,并且结合具体的例子,把伪代码转换成实际的代码。
各位看官,关于使用信号量进行进程间同步与互斥的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。
相关文章推荐
- VC++ 通过域名与服务器通信
- c++之路进阶——treap树(普通平衡树)
- c++ string trim
- c++之路进阶——treap树(郁闷的出纳员)
- 关于在ubuntu下eclipse中c++11支持和编译运行c++11报错的解决方法
- C语言实现封装、继承和多态
- c++之路进阶——块状链表(弹飞绵羊)
- 适配器模式 C++实现
- 基于 intel MKL 的对称矩阵特征值求解器
- [转] C语言常见笔试题大全1
- c++之路进阶——块状链表(教主的魔法)
- C++实现单链表
- C/C++——sizeof和strlen的区别
- C++预定义字符函数
- vc++ 读取指定文件夹下所有文件名
- 2、C++
- C++基础篇 -- vector的resize函数和reserve函数
- C语言文件打开模式(r/w/a/r+/w+/a+/rb/wb/ab/rb+/wb+/ab+)浅析
- 【C++】【斐波那契】求第几个斐波那契数字。
- RHEL安装 C++ 编译器