目录

一、Linux进程间通信概述

1.UNIX平台进程通信方式

2.常用的进程间通信方式

二、无名管道PIPE

1.无名管道的特点:

2.无名管道的创建与关闭

创建无名管道

无名管道的读写

无名管道的读写特性

管道破裂例子

无名管道的大小

三、有名管道FIFO

1.有名管道的创建

 2.有名管道进行通信例子


一、Linux进程间通信概述

1.UNIX平台进程通信方式

早期进程间通信方式:
AT&T的贝尔实验室,对Unix早期的进程间通信进行了改进和扩充,形成了“system V IPC”,其通

信进程主要局限在单个计算机内

BSD(加州大学伯克利分校的伯克利软件发布中心),跳过了该限制,形成了基于套接字(socket)的进程间通信机制
Linux继承了上述所有的通信方式

2.常用的进程间通信方式

1)传统的进程间通信方式
无名管道(pipe)、有名管道(fifo)和信号(signal)
2)System V IPC对象
共享内存(share memory)、消息队列(message queue)和信号灯(semaphore)
3)BSD
套接字(socket  用于网络通信)

二、无名管道PIPE

1.无名管道的特点:

1)只能用于具有亲缘关系的进程之间的通信;

 

2)半双工的通信模式,具有固定的读端和写端;

 

3)管道可以看成是一种特殊的文件,对于它的读写可以使用文件IO如read、write函数

2.无名管道的创建与关闭

无名管道是基于文件描述符的通信方式(但这个文件在文件系统中不可见)。当一个管道建立时,它会
创建两个文件描述符fd[0]和fd[1]。 其中fd[0]固定用于读管道,而fd[1]固定用于写管道。
构成了一个半双工的通道。

创建无名管道

首先来看创建函数

eg:

int main()
{
int pfd[2];
if (pipe(pfd) < 0) /*创建无名管道*/
{
printf("pipe create error\n");//利用返回值判断是否创建成功
return -1;
}
else
{
printf("pipe create success\n");
}
close(pfd[0]); /*关闭管道描述符*/
close(pfd[1]);
}

无名管道的读写

先举个例子实现子进程写入父进程读出

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{ int pfd[2] = {0};//创建无名管道int ret = pipe(pfd);if(ret < 0){perror("pipe");exit(-1);}pid_t pid = fork();//创建子进程if(pid < 0){perror("fork");exit(-1);}if(pid == 0){char buf[64] = {0};//自定义缓冲区,用于存入终端输入信息while(1){fgets(buf, 64, stdin);buf[strlen(buf)-1] = '\0';    write(pfd[1], buf, strlen(buf));//子进程执行写操作}}else{char buf1[64] = {0};while(1)//父进程进行读操作{memset(buf1, 0, 64);//清空缓冲区操作,因为自定义缓冲区可能存在上次读入的数据read(pfd[0], buf1, 64);printf("father ---- %s\n", buf1);//展示读入的数据}wait(NULL);//回收子进程资源exit(0);}return 0;
} 

无名管道的读写特性

读特性:

当写端存在时:

管道有数据:返回读到的字节数

管道无数据:阻塞

当写端不存在时:

管道有数据:返回读到的数据

管道无数据:返回0;

写特性:

当读端存在时:

管道有空间:返回写入的字节数

管道无空间:阻塞,直到有空间为止

当读端不存在时:

无论管道是否有空间,管道破裂 SIGPIPE

管道破裂例子

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>int main(int argc, char *argv[])
{ int pfd[2] = {0};int ret = pipe(pfd);   //创建无名管道if(ret < 0){perror("pipe");exit(-1);}close(pfd[0]);         //关闭无名管道的读端pid_t pid = fork();     //创建子进程if(pid == 0){write(pfd[1], "hello", 5);sleep(5);}else{int status;wait(&status);printf("%d %d %d\n", WIFEXITED(status),WIFSIGNALED(status),WTERMSIG(status));//展示错误信息exit(0);}return 0;
} 

无名管道的大小

可以以下方式计算

#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{ int pfd[2] = {0};pipe(pfd);int ret = 0;int size = 0;char buf[1] = {0};while(1)//一直往管道里写数据{ret = write(pfd[1], buf, 1);//利用write返回值来计算,write会返回写入的字节数,这里我们一次就写一个0,然后循环进行累加,直到管道被塞满size = size+ret;printf("size = %d\n", size);}return 0;
} 

这里注意几个要点

1)当管道中无数据时,读操作会阻塞
2)向管道中写入数据时,linux将不保证写入的原子性,管道缓冲区一有空闲区域,写进程就会试图向管道写入数据。如果读进程不读走管道缓冲区中的数据,那么写操作将会一直阻塞。
3)只有在管道的读端存在时,向管道中写入数据才有意义。否则,向管道中写入数据的进程将收到内核传来的SIGPIPE信号(通常Broken pipe错误)。

三、有名管道FIFO

1)无名管道只能用于具有亲缘关系的进程之间,这就限制了无名管道的使用范围有名管道可以使互不相关的两个进程互相通信。
2)有名管道可以通过路径名来指出,并且在文件系统中可见进程通过文件IO来操作有名管道( 意思就是在系统文件中可见 )
3)有名管道遵循先进先出规则
4)不支持如lseek() 操作

1.有名管道的创建

因为有名管道是一个文件,所以在操作有名文件时,要先创建一个有名文件,且操作时也有open和close操作

创建例子

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{ int ret = mkfifo("fifo", 0664);//文件属性一般为0664if(ret < 0){perror("mkfifo");exit(-1);}return 0;
} 

2.有名管道进行通信例子

读操作进程

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>int main(int argc, char *argv[])
{ int fd = open("fifo", O_RDONLY);if(fd < 0){perror("open");exit(-1);}printf("open fifo ok!\n");char buf[64] = {0};while(1){memset(buf, 0, 64);read(fd, buf, 64);printf("%s\n", buf);}close(fd);return 0;
} 

写操作进程

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>int main(int argc, char *argv[])
{ int fd = open("fifo", O_WRONLY);if(fd < 0){perror("open");exit(-1);}printf("open fifo ok!\n");char buf[64] = {0};while(1){fgets(buf, 64, stdin);buf[strlen(buf)-1] = '\0';write(fd, buf, strlen(buf));}close(fd);return 0;
} 

注:两个进程要同在运行状态,管道的读写操作才能执行,如果只有一方运行,程序会一直程阻塞状态

Linux进程间通信——管道通信相关推荐

  1. 【流媒体服务器Mediasoup】 NodeJs与C++信令通信详解及Linux下管道通信的详解(五)

    目录 前言 匿名管道进程间通信 进程间管道 的创建与图解 MediaSoup中的管道创建 MediaSoup Channel的创建 NodeJs和 C++ 管道通信的过程 MediaSoup 消息确认 ...

  2. #Linux#进程间通信# 管道(pipe)-标准流管道pipe

    在#Linux#进程间通信# 管道(pipe)-普通管道pipe中,我们很容易可以看出普通管道一是单工,即只能单向传输,而标准流管道针对匿名管道PIPE一系列封装.返回文件流.只不过返回的文件流无法使 ...

  3. linux程序间管道通信,linux进程间通信——管道 详解

    管道是Linux中很重要的一种通信方式,是把一个程序的输出直接连接到另一个程序的输入.常说的管道多是指无名管道, 无名管道只能用于具有亲缘关系的进程之间,这是它与有名管道的最大区别. 有名管道叫nam ...

  4. Linux进程间通信——管道

    转自:http://www.cnblogs.com/feisky/archive/2010/03/24/1693484.html Linux进程间通信机制: 1.同一主机进程间通信机制: Unix方式 ...

  5. Linux进程间通信(管道、消息队列、共享内存、信号、信号量)

    目录 Linux进程间通信概述 1.管道 无名管道(pipe) 有名管道(fifo) 2.消息队列(msg) 消息队列的通信原理 消息队列相关api 消息队列收发数据 键值生成 消息队列移除 3.共享 ...

  6. 【Linux】管道通信

    现在Linux进程间通信方式包括:无名管道(pipe)及有名管道(fifo).信号(signal).消息队列(message queue).共享内存(shared memory).信号量(semaph ...

  7. linux进程管道通信缺点,Linux 进程间通信(1) -- 管道

    进程间通信(IPC - InterProcess Communication) 通信的方式有很多: 文件, 管道, 信号, 共享内存, 消息队列, 套接字, 命名管道等等; 但是由于设计缺陷现在常用的 ...

  8. Linux下进程间通信-------管道通信

    先来看原理: 特点 : 1.半双工的通信方式(通信期间双方都可以发送/接收文件,但是不能双方同时发送/接收数据) 2.pipe只能用于父子进程间的通信 3.mkfifo可用于任意进程间的通信 代码逐步 ...

  9. linux 命名管道通信速度,《Linux 进程间通信》命名管道:FIFO

    命名管道的主要用途:不相关的进程之间交换数据. 命令行上创建命名管道: $ mkfifo filename 程序中创建命名管道: #include #include int mkfifo(const ...

最新文章

  1. 【J2SE】学习基础
  2. 重大里程碑!VOLO屠榜CV任务,无需额外数据,首次在ImageNet 上达到87.1%
  3. [转]使用批处理设置、启动和停止服务
  4. c++引用专题之常引用
  5. SQL Server分页查询存储过程
  6. Java并发:隐藏线程死锁
  7. 关闭TCP连接的学问
  8. escilpe mysql,wordpress函数esc_sql()用法示例
  9. 高通平台printk输出log到串口
  10. python函数的及函数的参数的基本使用
  11. 新罗马字体linux,WPS文字办公—将阿拉伯数字替换为新款Times New Roman字体
  12. Google Guice依赖注入框架使用
  13. SWFUpload使用指南
  14. 电脑间通过串口传输数据【串口练习】
  15. 什么是逻辑主键和业务主键
  16. lm283_飞利浦LED泛光灯具 BVP283 LED户外照明灯具350W 超高功率泛光灯
  17. IP,域名,DNS,端口
  18. 虹科资讯| 虹科AR荣获汽车后市场“20佳”维修工具评委会提名奖!
  19. 【Mapreduce】Mapreduce实例——WordCount
  20. 湘潭大学计算机考研复试题,湘潭大学信息工程学院2019考研复试程序设计练习题...

热门文章

  1. 易查查:外贸通过这个方法找采购商邮箱百发百中
  2. Mysql出现问题:ERROR 1160 ( 08S01 (ER_NET_ERROR_ON_WRITE)): Got an error writing communication packe解决方案
  3. fragment简介
  4. 日本人为何离开名片就寸步难行?
  5. 如何查看文件的MD5值?
  6. getPath(),getAbsolutePath(),getCanonicalPath() 返回文件的路径
  7. python爬取豆瓣书籍_python爬虫学习,爬取豆瓣各分类书单
  8. 昝同学的Python 5.24
  9. 联想yoga 14s 2021标压版怎么样?测评值得买吗?详细性能点评
  10. EasyExcel合并列(横向合并)