1>管道,FIFO
端句柄的进程通信。管道可以是单向-一端是只读的,另一端点是只写的;也可以
是双向的一管道的两端点既可读也可写。
匿名管道(Anonymous Pipe)是 在父进程和子进程之间,或同一父进程的两个子
进程之间传输数据的无名字的单向管道。通常由父进程创建管道,然后由要通信的
子进程继承通道的读端点句柄或写 端点句柄,然后实现通信。父进程还可以建立两
个或更多个继承匿名管道读和写句柄的子进程。这些子进程可以使用管道直接通信
,不需要通过父进程。
匿名管道是单机上实现子进程标准I/O重定向的有效方法,它不能在网上使用,
也不能用于两个不相关的进程之间
双向管道。不同于匿名管道的是命名管道可以在不相关的进程之间和不同计算机之
间使用,服务器建立命名管道时给它指定一个名字,任何进程都可以通过该名字打
开管道的另一端,根据给定的权限和服务器进程通信。
命名管道提供了相对简单的编程接口,使通过网络传输数据并不比同一计算机
上两进程之间通信更困难,不过如果要同时和多个进程通信它就力不从心了。
型的管道,适合传递较小的消息,FIFO实际相当于内核内部实现的一个共享文件。
2>信号
程间通信外,进程还可以发送信号给进程本身。除了系统内核和root之外,只有具
备相同uid、gid的进程才可以使用信号进行通信。
3> 消息队列
的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消
息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限
等缺。
4> 共享内存
信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到
进程间的同步及互斥。
传递文件最好是用共享内存的方式,MAP_SHARED可以提供多进程共享一个文件的能
力。
管道 和 FIFO 是一样的,只是匿名管道需要在 父子进程间使用,FIFO是增强型的
管道,适合传递较小的消息,FIFO实际相当于内核内部实现的一个共享文件。
信号,严重的不建议使用,尤其是你的线程库不能做到异步安全的时候,使用信号
作为通信方式很容易导致系统死锁。
消息队列 与 FIFO 相似,是在FIFO的基础上封装的一个消息结构队列。
建议使用 FIFO 或消息队列传递控制类型的消息(数据量小,有明确的数据结构)
使用共享内存传递数据类型的消息(数据量大,数据结构多变)
linux下进程间通信的几种主要手段简介:
- 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;
- 信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数);
- 报文(Message)队列(消息队列):消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
- 共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
- 信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
- 套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。
或许你会有疑问,那多线程间要通信,应该怎么做?前面已经说了,多数的多线程都是在同一个进程下的,它们共享该进程的全局变量,我们可以通过全局变量来实现线程间通信。如果是不同的进程下的2个线程间通信,直接参考进程间通信。