操作系统 进程间的通信 之 信号 消息队列 共享内存 浅析

【几个易混淆的相关概念】

  • 进程互斥:指在多道程序环境下,每次只允许一个进程对临界资源进行访问。   
  • 进程同步:指多个相关进程在执行次序上的协调。   
  • 临界资源:在一段时间内只允许一个进程访问的资源。   
  • 临界区:每个进程中访问临界资源的那段代码。
【进程通信】

现在常用的进程间通信方式有信号、信号量、消息队列、共享内存。通信,是一个广义的意义,不仅仅指传递一些 message。进程通信就是指不同进程之间进程数据共享和数据交换。

【信号和信号量】

信号和信号量是不同的,他们虽然都可用来实现同步和互斥,但信号是使用信号处理器来进行的,信号量是使用P、V操作来实现的。

【信号量】

信号量又称为信号灯,信号量(semaphore)的数据结构为一个值和一个指针,指针指向等待该信号量的下一个进程。它是用来协调不同进程间的数据对象的,而最主要的应用是共享内存方式的进程间通信。本质上,信号量是一个计数器,它用来记录对某个资源(如共享内存)的存取状况。一般说来,为了获得共享资源,进程需要执行下列操作: 

   (1) 测试控制该资源的信号量。 
   (2) 若此信号量的值为正,则允许进行使用该资源。进程将信号量减1。 
   (3) 若此信号量为0,则该资源目前不可用,进程进入睡眠状态,直至信号量值大于0,进程被唤醒,转入步骤(1)。 
   (4) 当进程不再使用一个信号量控制的资源时,信号量值加1。如果此时有进程正在睡眠等待此信号量,则唤醒此进程。 
信号量的值与相应资源的使用情况有关。当它的值大于0时,表示当前可用资源的数量;当它的值小于0时,其绝对值表示等待使用该资源的进程个数。注意,信号量的值仅能由P V操作来改变。
http://www.cnblogs.com/biyeymyhjob/archive/2012/07/21/2602015.html

【P V操作】
  • P V操作的定义

P V操作由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作。

P:Passeren(通过)

是申请等待可用资源S,意味着请求分配一个单位资源,S--,Wait(s)

V: virjgeren(释放)

是用了资源S后释放发出信号,意味着释放一个单位资源,S++,Signal(s)

P(S):①将信号量S的值减1,即S=S-1;

                 ②如果S>0,则该进程继续执行;否则该进程置为等待状态,排入等待队列。
V(S):①将信号量S的值加1,即S=S+1;

                 ②如果S>0,则该进程继续执行;否则释放队列中第一个等待信号量的进程。

  • P V操作的意义

我们用信号量及PV操作来实现进程的同步和互斥。PV操作属于进程的低级通信。 

【PV操作实现进程间的同步和互斥】

  • 利用信号量和P、V操作实现进程互斥

利用信号量和P、V操作实现进程互斥的一般模型是:


进程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操作实现进程同步

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/pp0xx0ww0/article/details/8701735

你可能感兴趣的:(操作系统,进程,通信,信号量,消息队列,共享内存)