【几个易混淆的相关概念】
【进程通信】
现在常用的进程间通信方式有信号、信号量、消息队列、共享内存。通信,是一个广义的意义,不仅仅指传递一些 message。进程通信就是指不同进程之间进程数据共享和数据交换。
信号和信号量是不同的,他们虽然都可用来实现同步和互斥,但信号是使用信号处理器来进行的,信号量是使用P、V操作来实现的。
【信号量】
信号量又称为信号灯,信号量(semaphore)的数据结构为一个值和一个指针,指针指向等待该信号量的下一个进程。它是用来协调不同进程间的数据对象的,而最主要的应用是共享内存方式的进程间通信。本质上,信号量是一个计数器,它用来记录对某个资源(如共享内存)的存取状况。一般说来,为了获得共享资源,进程需要执行下列操作:
(1) 测试控制该资源的信号量。
(2) 若此信号量的值为正,则允许进行使用该资源。进程将信号量减1。
(3) 若此信号量为0,则该资源目前不可用,进程进入睡眠状态,直至信号量值大于0,进程被唤醒,转入步骤(1)。
(4) 当进程不再使用一个信号量控制的资源时,信号量值加1。如果此时有进程正在睡眠等待此信号量,则唤醒此进程。
信号量的值与相应资源的使用情况有关。当它的值大于0时,表示当前可用资源的数量;当它的值小于0时,其绝对值表示等待使用该资源的进程个数。注意,信号量的值仅能由PV操作来改变。
http://www.cnblogs.com/biyeymyhjob/archive/2012/07/21/2602015.html
PV操作由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作。
P:Passeren(通过)
是申请等待可用资源S,意味着请求分配一个单位资源,S--,Wait(s)
V: virjgeren(释放)
是用了资源S后释放发出信号,意味着释放一个单位资源,S++,Signal(s)
②如果S>0,则该进程继续执行;否则该进程置为等待状态,排入等待队列。
P(S):①将信号量S的值减1,即S=S-1;
V(S):①将信号量S的值加1,即S=S+1;②如果S>0,则该进程继续执行;否则释放队列中第一个等待信号量的进程。
我们用信号量及PV操作来实现进程的同步和互斥。PV操作属于进程的低级通信。
【PV操作实现进程间的同步和互斥】
利用信号量和PV操作实现进程互斥的一般模型是:
进程P1 进程P2 …… 进程Pn …… …… …… …… P(S) P(S) …… P(S) 临界区 临界区 …… 临界区 V(S) V(S) …… V(S)
使用PV操作实现进程互斥时应该注意的是:
(1)每个程序中用户实现互斥的P、V操作必须成对出现,先做P操作,进临界区,后做V操作,出临界区。若有多个分支,要认真检查其成对性。
(2)P、V操作应分别紧靠临界区的头尾部,临界区的代码应尽可能短,不能有死循环。
(3)互斥信号量S的初值一般为1。
PV操作是典型的同步机制之一。用一个信号量与一个消息联系起来,当信号量的值为0时,表示期望的消息尚未产生;当信号量的值非0时,表示期望的消息已经存在。用PV操作实现进程同步时,调用P操作测试消息是否到达,调用V操作发送消息。
使用PV操作实现进程同步时应该注意的是:
(1)分析进程间的制约关系,确定信号量种类。在保持进程间有正确的同步关系情况下,哪个进程先执行,哪些进程后执行,彼此间通过什么资源(信号量)进行协调,从而明确要设置哪些信号量。
(2)信号量的初值与相应资源的数量有关,也与P、V操作在程序代码中出现的位置有关。
(3)同一信号量的P、V操作要成对出现,但它们分别在不同的进程代码中。
http://blog.csdn.net/Jesse621/article/details/8039071
信号量机制是一种卓有成效的进程同步工具,被广泛应用于单处理机和多处理机系统,以及计算机网络中。
【消息队列】
消息队列,是一种比较高级的进程间通信的方法,它可以再进程间传送message,还可以传送一个“I seek you”。
【共享内存】消息队列也称为报文队列,消息队列是随内核持续的,只有在内核重起或显示删除一个消息队列时,该消息队列才会真正删除 系统中记录消息队列的数据结构struct ipc_ids msg_ids位于内核中,系统中所有消息队列都可以在结构msg_ids中找到访问入口
消息队列其实就是一个消息的链表,每个消息队列有一个队列头,称为struct msg_queue,这个队列头描述了消息队列的key值,用户ID,组ID等信息,但它存于内核中而结构体struct msqid_ds能够返回或设置消息队列的信息,这个结构体位于用户空间中,与msg_queue结构相似消息队列允许一个或多个进程向它写入或读取消息,消息队列是消息的链表。
消息是按消息类型访问,进程必须指定消息类型来读取消息,同样,当向消息队列中写入消息时也必须给出消息的类型,如果读队列使用的消息类型为0,则读取队列中的第一条消息。
内核空间的结构体msg_queue描述了对应key值消息队列的情况,而对应于用户空间的msqid_ds这个结构体,因此,可以操作msgid_ds这个结构体来操作消息队列。
共享内存是运行在同一台机器上的进程间通信最快的方式,因为数据不需要在不同的进程间复制。通常由一个进程创建一块共享内存区,其余进程对这块内存区进行读写。共享内存往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
函数原型说明见:http://www.cnblogs.com/biyeymyhjob/archive/2012/08/04/2623323.html
程序实例:参见http://blog.csdn.net/yangzhongxuan/article/details/7925750
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u013630349/article/details/46823335