进程间通信(IPC)方式

时间:2022-05-13 14:25:06

进程间通信(IPC)方式

1.进程间通信(IPC)主要方式:管道、系统IPC(消息队列 ,信号量,信号,共享内存)socket

  1. 匿名管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,只能用于父子进程通讯。

    高级管道(popen):将另一个程序当做一个新的进程在当前程序进程中启动,则它算是当前程序的子进程,这种方式我们成为高级管道方式。
    命名管道 (named pipe) : 有名管道也是半双工的通信方式,可用于非父子进程,就是FIFO先进先出的通讯方法。
    消息队列( message queue ) : 消息队列是有消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点首先在一个进程中创建一个消息队列,然后再往消息队列中写入数据,另一个进程从队列中取数据。注意:消息队列是用创建文件的方式建立的,如果一个进程向某个消息队列中写入数据后,另一个线程没有取,即时通信关闭后,保存在消息队列中的数据也没有消失,下次在用这个消息队列读数据的时候就是上次写的。

  • 信号量( semophore ) : 进程间通信处理同步互斥机制。信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源,保证两个或者多个关键代码段不被并发调用。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。多线程模式下防止多个程序不能同时访问临界区。
    信号 ( sinal ) :一种处理异步事件的方式。 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生,除了用于进程外,还可以发送信号给进程本身(比如kill函数)
    共享内存( shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信
    套接字( socket ) : socket也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。

  • 2、比较

  • (1)管道:速度慢,容量有限,只有父子进程能通讯

    (2)FIFO:任何进程间都能通讯,但速度慢

    (3)消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题

    (4)信号量:不能传递复杂消息,只能用来同步

    (5)共享内存区:能够很容易控制容量,速度快但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了同一进程内的一块内存

    管道单独构成一种独立的文件系统:管道对于两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在于内存中。这就与共享内存存在几分相似,但是灵活性方面不如共享内存。

    消息队列在内核中,但其消息是汇集于内核,这就造成其消息队列长度的限制。这与信号灯存在几分相似。

    名称空间 标识符 路径名,两种不同方式(让其它进程找到你)。

    随内核或随进程持续,存在内核中便于其它进程查找(名称空间)。。。,当然存在内核中不是唯一的方法,管道就是一个例子,利用文件系统

  • 3、注意:

  • (1)信号和信号量的区别:

  • 信号信号量是不同的,虽然它们都可以实现进程的同步和互斥,但是信号是使用信号处理器来进行的,信号量是使用p v 操作来实现的。

  •  信号量是一种特殊的变量,实际上就是用来控制进程状态的一个代表某一资源的存储单元表现形式是一个整型S和一个队列.

  •     PV操作:

        P操作和V操作是执行时不被打断的两个操作系统原语。执行P操作P(S)时信号量S的值减1,若结果不为负则P(S)执行完毕,否则执行P操作的进程暂停以等待释放。执行V操作V(S)时,S的值加1,若结果不大于0则释放一个因执行P(S)而等待的进程.进程间通信(IPC)方式

        P操作:也称为down()/wait()操作,使S=S-1,若S<0,进程暂停执行,放入信号量的等待队列.

        V操作:也称为up()/signal()操作,使S=S+1,若S<=0,唤醒等待队列中的一个进程.


  • 信号的使用过程:首先初始化信号集(信号集中的信号才会被考虑,两种方法:设置空信号集 将所有信号添加到信号集)其次安装信号处理器(对特定信号赋予信号处理函数)每个信号都有一个信号处理器。之后接受信号 信号处理器就可以工作了。