进程间通信的方式主要有:管道,共享内存,信号量,消息队列。

详细参考https://blog.csdn.net/skyroben/article/details/71513385

1.进程间通信

   每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程A把数据从用户空间拷到内核缓冲区,进程B再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信。12

不同进程间的通信本质:进程之间可以看到一份公共资源;而提供这份资源的形式或者提供者不同,造成了通信方式不同,而 pipe就是提供这份公共资源的形式的一种。

2.匿名管道

2.1管道的创建

   管道是由调用pipe函数来创建12
#include <unistd.h>int pipe (int fd[2]);                         //返回:成功返回0,出错返回-1     123
 fd参数返回两个文件描述符,fd[0]指向管道的读端,fd[1]指向管道的写端。fd[1]的输出是fd[0]的输入。12

2.2管道如何实现进程间的通信

(1)父进程创建管道,得到两个⽂件描述符指向管道的两端

(2)父进程fork出子进程,⼦进程也有两个⽂件描述符指向同⼀管道。

(3)父进程关闭fd[0],子进程关闭fd[1],即⽗进程关闭管道读端,⼦进程关闭管道写端(因为管道只支持单向通信)。⽗进程可以往管道⾥写,⼦进程可以从管道⾥读,管道是⽤环形队列实现的,数据从写端流⼊从读端流出,这样就实现了进程间通信。 

2.3如和用代码实现管道通信

[cpp] view plain copy

  1. #include <stdio.h>

  2. #include <unistd.h>

  3. #include <string.h>

  4. #include <errno.h>

  5. int main()

  6. {

  7. int fd[2];

  8. int ret = pipe(fd);

  9. if (ret == -1)

  10. {

  11. perror(”pipe error\n”);

  12. return 1;

  13. }

  14. pid_t id = fork();

  15. if (id == 0)

  16. {//child

  17. int i = 0;

  18. close(fd[0]);

  19. char *child = “I am  child!”;

  20. while (i<5)

  21. {

  22. write(fd[1], child, strlen(child) + 1);

  23. sleep(2);

  24. i++;

  25. }

  26. }

  27. else if (id>0)

  28. {//father

  29. close(fd[1]);

  30. char msg[100];

  31. int j = 0;

  32. while (j<5)

  33. {

  34. memset(msg,’\0’,sizeof(msg));

  35. ssize_t s = read(fd[0], msg, sizeof(msg));

  36. if (s>0)

  37. {

  38. msg[s - 1] = ’\0’;

  39. }

  40. printf(”%s\n”, msg);

  41. j++;

  42. }

  43. }

  44. else

  45. {//error

  46. perror(”fork error\n”);

  47. return 2;

  48. }

  49. return  0;

  50. }

1

运行结果:

每隔2秒打印一次I am child!        并且打印了五次。1212

2.4管道读取数据的四种的情况

(1)读端不读,写端一直写 

(2)写端不写,但是读端一直读 

(3)读端一直读,且fd[0]保持打开,而写端写了一部分数据不写了,并且关闭fd[1]。 

如果一个管道读端一直在读数据,而管道写端的引⽤计数⼤于0决定管道是否会堵塞,引用计数大于0,只读不写会导致管道堵塞。

(4)读端读了一部分数据,不读了且关闭fd[0],写端一直在写且f[1]还保持打开状态。

[cpp] view plain copy

  1. #include <stdio.h>

  2. #include <unistd.h>

  3. #include <string.h>

  4. #include <errno.h>

  5. int main()

  6. {

  7. int fd[2];

  8. int ret = pipe(fd);

  9. if (ret == -1)

  10. {

  11. perror(”pipe error\n”);

  12. return 1;

  13. }

  14. pid_t id = fork();

  15. if (id == 0)

  16. {//child

  17. int i = 0;

  18. close(fd[0]);

  19. char *child = “I am  child!”;

  20. while (i<10)

  21. {

  22. write(fd[1], child, strlen(child) + 1);

  23. sleep(2);

  24. i++;

  25. }

  26. }

  27. else if (id>0)

  28. {//father

  29. close(fd[1]);

  30. char msg[100];

  31. int status = 0;

  32. int j = 0;

  33. while (j<5)

  34. {

  35. memset(msg, ’\0’, sizeof(msg));

  36. ssize_t s = read(fd[0], msg, sizeof(msg));

  37. if (s>0)

  38. {

  39. msg[s - 1] = ’\0’;

  40. }

  41. printf(”%s  %d\n”, msg, j);

  42. j++;

  43. }

  44. //写方还在继续,而读方已经关闭它的读端

  45. close(fd[0]);

  46. pid_t ret = waitpid(id, &status, 0);

  47. printf(”exitsingle(%d),exit(%d)\n”, status & 0xff, (status >> 8) & 0xff);

  48. //低八位存放该子进程退出时是否收到信号

  49. //此低八位子进程正常退出时,退出码是多少

  50. }

  51. else

  52. {//error

  53. perror(”fork error\n”);

  54. return 2;

  55. }

  56. return  0;

  57. }

1

运行结果:

使用kill -l 查看13号信号,可以知道13号信号代表SIGPIPE。

总结: 
如果一个管道的写端一直在写,而读端的引⽤计数是否⼤于0决定管道是否会堵塞,引用计数大于0,只写不读再次调用write会导致管道堵塞; 
如果一个管道的读端一直在读,而写端的引⽤计数是否⼤于0决定管道是否会堵塞,引用计数大于0,只读不写再次调用read会导致管道堵塞; 
而当他们的引用计数等于0时,只写不读会导致写端的进程收到一个SIGPIPE信号,导致进程终止,只写不读会导致read返回0,就像读到⽂件末尾⼀样。

2.5管道特点

1.管道只允许具有血缘关系的进程间通信,如父子进程间的通信。2.管道只允许单向通信。3.管道内部保证同步机制,从而保证访问数据的一致性。4.面向字节流5.管道随进程,进程在管道在,进程消失管道对应的端口也关闭,两个进程都消失管道也消失。1234567891012345678910

2.6管道容量大小

测试管道容量大小只需要将写端一直写,读端不读且不关闭fd[0],即可。 
测试代码:

#include <stdio.h>#include <unistd.h>#include <string.h>#include <errno.h>int main()
{    int fd[2];    int ret = pipe(fd);    if (ret == -1){perror("pipe error\n");        return 1;}pid_t id = fork();    if (id == 0){//childint i = 0;close(fd[0]);        char *child = "I am  child!";        while (i++){write(fd[1], child, strlen(child) + 1);            printf("pipe capacity: %d\n", i*(strlen(child) + 1));}close(fd[1]);}    else if (id>0){//fatherclose(fd[1]);waitpid(id, NULL, 0);}    else{//errorperror("fork error\n");        return 2;}    return  0;
}1234567891011121314151617181920212223242526272829303132333435363738

可以看到写到65520之后管道堵塞了,而65520即为64K大小即为管道的容量。 

转载于:https://blog.51cto.com/jack88/2141792

进程间通信的几种方式相关推荐

  1. android中进程间通信的几种方式

    进程间通信(IPC)方式 使用Bundle 使用文件共享 使用Messenger 使用AIDL 使用COntentProvider 使用Socket 一.使用Bundle 我们都知道Android中三 ...

  2. 一文读懂Python进程间通信的几种方式

    为什么进程之间需要通信? 1.数据传输 一个进程需要将它的数据发送给另一个进程; 2.资源共享 多个进程之间共享同样的资源; 3.事件通知 一个进程需要向另一个或一组进程发送消息,通知它们发生了某种事 ...

  3. 【操作系统】进程间通信的五种方式

    引言 1.进程对白:管道.记名管道.套接字 1.管道 2.虫洞:套接字 3.信号 4.信号旗语:信号量 5.进程拥抱:共享内存 引言 进程作为人类的发明,自然免不了脱离人类的习性,也有通信需求.如果进 ...

  4. Electron主进程渲染进程间通信的四种方式

    在electron中进程使用 ipcMain 和 ipcRenderer 模块,通过开发人员定义的"通道"传递消息来进行通信.新的版本中electron推荐使用上下文隔离渲染器进程 ...

  5. 进程间通信那种效率最高_进程间通信的几种方式的介绍及比较

    进程间通信就是在不同进程之间传播或交换信息,那么不同进程之间存在着什么双方都可以访问的介质呢?进程的用户空间是互相独立的,一般而言是不能互相访问的,唯一的例外是共享内存区.但是,系统空间却是" ...

  6. 进程间通信的5种方式

    五种进程间通信的方式: 共享内存(shared memory):其允许多个进程通过读写同一块内存地址来相互通信. 内存映射(Mapped memory):其和共享内存相似,然而它是和文件系统上的一个文 ...

  7. Android进程间通信的几种方式

    首先,介绍一下,什么是RPC RPC(Remote Procedure Call)即远程过程调用,它是一种通过网络从远程计算机程序上请求服务,在不需要了解底层网络技术的协议下,即可获取计算机进程中的数 ...

  8. Linux进程间通信的几种方式总结-——linux内核剖析

    进程间通信概述 Linux内核通信相关视频讲解:Linux内核,进程间通信组件的实现 linux内核,进程调度器的实现,内核源码分析 进程通信的目的 传输数据 一个进程须要将它的数据发送给还有一个进程 ...

  9. 进程间通信的8种方式

    前言: 进程通信: 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程A把数据从用户空间拷到内核缓冲区,进 ...

最新文章

  1. 和12岁小同志搞创客开发:设计一款亮度可调节灯
  2. 用C语言解“BCD解密”问题
  3. jQuery Ajax调用后如何管理重定向请求
  4. 占内存小的qq_手机内存空间告急,这些办法就能轻松搞定!
  5. 又是一天,这次是网页显示的问题
  6. 开发好能重构的代码,都是这么干的
  7. JavaEye站长对OpenSocial与Facebook平台的比较
  8. (IOS)Swift Music 程序分析
  9. android 文件管理 免root,真正免root的RE文件管理器(Root Explorer)详细使用教程
  10. 百度网盘获取下载链接
  11. 级差公排php如何_矩阵,双轨,级差三种制度的对话
  12. 全球四大国际反垃圾邮件组织介绍
  13. 自己计算机设置盘密码怎么操作,电脑硬盘,教您电脑硬盘怎么设置密码
  14. 【自动化测试】Selenium IDE脚本编辑与操作(了解)
  15. p2p sdk接收文件服务端epoll模型源码
  16. linux下wifi设备的实现逻辑
  17. MCUXpresso开发RT1060(1)——使用RGB接口LCD
  18. 笔记本下键android,安卓联姻Windows?华硕双系统变形本体验
  19. 对于TGA格式文件的分析
  20. HEP World‘s Classics寄语

热门文章

  1. 2018:数据科学20个最好的Python库
  2. 波士顿动力的机器人会开门了,中国还要奋力追赶
  3. AI研究生应届生年薪可达50万 没出校门已被抢光
  4. Spring MVC 过时了吗?
  5. 字节跳动一面:i++ 是线程安全的吗?
  6. 搞了半天,终于弄懂了TCP Socket数据的接收和发送,太难~
  7. 老板说“把系统升级到https”,我用一个脚本实现了,而且永久免费!
  8. 深度学习如炼丹,你有哪些迷信做法?网友:Random seed=42结果好
  9. ICML 2021刚刚做出了一个「艰难的决定」:将论文接收率直接砍掉10%
  10. 魔改Attention大集合