【Linux】——进程间通信方式优缺点比较

这里也体现出管道的缺点——效率低下,我给你传数据,但是只有你把数据拿走了,我才能返回,这样是很慢的,不适合频繁通信的进程 。但同时也有一个优点,那就是可以保证你是真的拿到了我的数据 。
以下是一个关于命名管道完整代码的实例:
我们首先创建一个命名管道,如果成功,则关闭他的读端,向里面写入数据 。
#include #include #include #include #include #include #define FIFO "/tmp/fifo"#define MAX_LEN 128int main(void){int writeFd;char line[MAX_LEN] = {0};if(mkfifo(FIFO,S_IRUSR|S_IWUSR) < 0 && (errno != EEXIST)){perror("make fifo failed:");return -1;}/*关闭管道的读描述符*/writeFd = open(FIFO,O_WRONLY,0);/*向管道写入数据*/write(writeFd,"www.yanbinghu.com",sizeof("www.yanbinghu.com"));close(writeFd);return 0;}
然后再新的终端打开一个刚才创建的命名管道,从里面读取数据:
#include #include #include #include #include #include#define FIFO "/tmp/fifo"#define MAX_LEN 128int main(void){int readFd,n;char line[MAX_LEN] = {0};/*打开FIFO,这里打开可能失败,应该要对返回值处理*/readFd = open(FIFO,O_RDONLY,0);/*从FIFO读取数据*/n = read(readFd,line,MAX_LEN);printf("read %d bytes from pipe :%s\n",n,line);close(readFd);/*删除FIFO*/unlink(FIFO);return 0;}
然后运行写进程和读进程,这样两个没有亲缘关系的进程就可以通过匿名管道进行通信了 。
总结:
2、消息队列
学习了以上管道我们知道,a向b 写数据,只有b把数据读出,a才能返回,那我们能不能不等待,我把数据传给你,然后我立即返回呢?
其实是可以的,消息队列就可以解决这样的问题,a只要把给b的数据放进消息队列里面就可以了,b要用数据直接从消息队列取出 。
3、共享内存
针对消息队列的缺点,共享内存允许多个进程共享一个给定的存储区,由于他们是共享一块内存数据,减少了内存拷贝的时间,因此速度非常快 。
但这里我们可能会问:每个进程不是独立的吗?怎么可以共享内存呢?
其实,系统加载一个进程时,分配给进程的内存并不是实际的物理内存,而是虚拟内存空间,我们可以让两个进程各自拿出一块虚拟地址空间来,然后映射到相同的物理内存中,这样虽然两个进程有独立的虚拟地址空间,但有一部分是映射的相同的物理内存,这样就完成了内存共享机制,如下图所示:

【Linux】——进程间通信方式优缺点比较

文章插图
缺点:多进程竞争内存,类似于我们平常说的线程安全 。
4、信号量
一句话概括:信号量的本质就是一个计数器,用来实现进程之间的同步与互斥 。
例如信号量的初始值为1,然后a进程来访问共享内存的时候,我们把信号量的值设为0,然后b进程来访问共享内存的时候,看到信号量的值为0,就知道已经有人来访问内存了,那b就访问不了了 。所以说信号量也是进程间的一种通信方式 。
5、
以上我们所说的管道,消息队列,共享内存,信号量都是同一主机之间的通信,那两个相隔几千里的进程怎么进行通信呢?
答案就是,例如平时我们通过浏览器发起一个http请求,然后服务器给你返回对应的数据,这种就是采用了的通信方式,也就是说:它能用于不同计算机之间的不同进程间的通信 。
【【Linux】——进程间通信方式优缺点比较】总结