1.进程间通信(IPC)主要方式:管道、系统IPC(消息队列 ,信号量,信号,共享内存)socket
-
匿名管道( 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 操作来实现的。
PV操作:
P操作和V操作是执行时不被打断的两个操作系统原语。执行P操作P(S)时信号量S的值减1,若结果不为负则P(S)执行完毕,否则执行P操作的进程暂停以等待释放。执行V操作V(S)时,S的值加1,若结果不大于0则释放一个因执行P(S)而等待的进程.
P操作:也称为down()/wait()操作,使S=S-1,若S<0,进程暂停执行,放入信号量的等待队列.
V操作:也称为up()/signal()操作,使S=S+1,若S<=0,唤醒等待队列中的一个进程.
信号的使用过程:首先初始化信号集(信号集中的信号才会被考虑,两种方法:设置空信号集 将所有信号添加到信号集)其次安装信号处理器(对特定信号赋予信号处理函数)每个信号都有一个信号处理器。之后接受信号 信号处理器就可以工作了。