linux进程间的通信方式

0.总述

linux中进程间的通信手段有很多,本篇将会简单介绍进程间的通信方式及其特点,具体原理和相关代码演示可以参照各个专题.

单机通信
1.管道(内核提供,单工,自同步机制),分为命名管道和匿名管道;
2.mmap;
3.信号;
4.XSI(SYS V)类型的IPC,包括消息队列和共享内存;
5.Posix类型的IPC,包括消息队列和共享内存段;
多机通信
6.网络套接字socket.

1.匿名管道

匿名管道pipe
int pipe(int pipdfd[2]);
特点:
1.只能用于有血缘关系的进程间通信;
2.管道有两端,管道的数据流像是从管道的写端到读端;
3.管道的本质是一块内核缓冲区;
4.数据从管道读走就不存在了;
5.管道的实现实际上是环形队列;
6.默认情况下管道的读端和写端都是阻塞的.

2.命名管道

命名管道fifo
mkfifo
int mkfifo(const char *pathname,mode_t mode);
特点:
1.有无血缘关系的进程间都可以通过命名管道通信;
2.创建的fifo文件的大小为0,是linux文件类型之一;
3.使用fifo需要先创建一个fifo;
4.使用fifo完成通信两个进程必须打开相同的fifo文件;
5.效率比pipe低.

3.共享映射区

共享映射区mmap
void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
特点:
1.有无血缘关系都可以完成进程间通信;
2.如果完成没有血缘关系之间的通信必须使用文件;
3.如果使用的是MAP_SHARED(flags的可选值),则对内存的修改会反映到文件中去
4.需要注意mmap可能存在调用失败的情况;
5.匿名映射只能用于有血缘关系的进程间通信.

4.信号

信号
进程A给进程B发送信号的实现机制:本质上是进程A先给内核发送信号,然后内核给进程B发送信号。
信号相关函数:
1.信号注册函数:
  sighandler_t signal(int signum, sighandler_t handler);
  int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
2.信号的发送函数举例:
  int kill(pid_t pid, int sig);
  void abort(void);
  int raise(int sig);
  unsigned int alarm(unsigned int seconds);
  int setitimer(int which, const struct itimerval *new_value,struct itimerval *old_value);
3.信号集相关函数举例:
  sigempty
  sigaddset
  sigfillset
  sigismember
  sigdelset
  sigpromask
  sigpending
特点:
1.信号不能携带大量信息;
2.信号的优先级高,产生信号后会大端程序的执行;
3.编程中一般不建议使用信号完成进程间通信;
4.一般使用kill命令给一个进程发送信号,进程收到信号之后调用信号处理函数完成操作.

 

5.本地socket

本地socket通信
int socket(int domain, int type, int protocol);
1.本地socket通信既可以使用TCP也可以使用UDP;
2.如果使用TCP通信,bind的时候需要指定一个文件,若文件存在会报错,unlink删除.
3.读或者写其实都是通过文件描述符区操作内核的缓冲区;
4.编写流程,可以直接参考TCP或者UDP的开发流程.

 

6.SYSV-消息队列

7.SYSV-共享内存 

8.POSIX-消息队列

9.POSIX-消息队列

10.总结

1.对于二进制信号量,应该使用POSIX IPC semaphore.可用于加锁和解锁,对于线程之间使用匿名信号量,对于进程之间使用命名信号量.
2.对于进程间需要传递数据的形式,选择POSIX IPC消息队列,数据只能流向一个进程,不能进行消息的相互传递,比如一个进程作为服务器,管理一个消息队列,其余的进程只需要向此消息队列写入消息,而服务进程不能反向传给其他进程,因为其他进程并不管理此队列,这就是一对多的模型.
3.对于服务器端和客户端进程需要交互信息的形式,建议使用unix domain socket,这样会创建一个客户端到服务器的一对一通道,其实socket就是为了多主机通信而生吧.
4.对于消息队列,linux系统都会有一个限制,比如可发送的最大消息字节数,一个特定队列的最大字节数,系统中的最大消息队列的长度,系统中最大的消息数等,这些限制在使用时要注意.用ulimit命令看到的是Posix的,用命令ipcs看到的是SYSV的.

总结部分有参考:
https://blog.csdn.net/rikeyone/article/details/中关于Linux进程通信方式的部分.

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值