进程间通信——管道(有名管道、无名管道)
来源:互联网 发布:ubuntu安装 虚拟机 编辑:程序博客网 时间:2024/05/22 07:59
进程间通信:多个进程之间数据相互交换。
进程间通信的方式:信号、管道(无名管道、有名管道)、信号量、消息队列、共享内存、套接字。
进程的创建:pid_t fork(void);
管道的原理:
有名管道:应用于两个进程之间数据的单向传递。
创建:命令方式:mkfifo 函数方式:mkfifo()
打开:open
写数据:write
读数据:read
关闭:close
在文件目录数中有一个文件标示(管道文件)实际不占据磁盘空间,数据缓存在内存上。
阻塞运行函数:函数调用后不会立即返回,需要等待某些条件的发生才会返回,open操作管道文件时,阻塞运行的函数。
如果一个进程以只写(读)方式打开一个管道文件,open会阻塞运行,直到有一个以读(写)方式打开管道文件,open才会返回,进程才会接着运行。
read函数也会阻塞运行,直到写端写入数据或者所有的写端都关闭,read读取数据并且会将内存上的已读数据清空。
void mian(){ int fd = open("FIFO",O_WRONLY); if(fd == -1) { exit(0); } printf("FIFO open success\n"); //sleep(10); write(fd,"hello world",11); printf("write success\n"); close(fd);}void main(){ int fd = open("FIFO",O_RDONLY); if(fd == -1) { exit(0); } printf("FIFO open success\n"); char buff[128] = {0}; read(fd,buff,127); printf("read data:%s\n",buff); close(fd);}
练习:A 进程负责循环接受用户输入的数据, 以”end”为结束标志, B 进程负责统计用户输入的字母个数。
//testa 接受用户输入的数据,以end为结束标志#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <string.h>void main(){ int fd = open("FIFO",O_WRONLY); if(fd == -1) { exit(0); } while(1) { printf("please input:"); fflush(stdout); char arr[128] = {0}; fgets(arr,127,stdin); write(fd,arr,strlen(buff)-1); if(strncmp(buff,"end",3) == 0) { break; } } close(fd);}//testb 统计用户输入的字母个数#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <string.h>void main(){ int fd = open("FIFO",O_RDONLY); if(fd == -1) { exit(0); } while(1) { char buff[128] = {0}; int count = 0; read(fd,buff,127); if(strncmp(buff,"end",3) == 0) { break; } count += strlen(buff); printf("%d\n",count); } } close(fd);}
无名管道:无名是相对于有名而言的,其在使用时产生,不使用后释放。不会在系统上留下蛛丝马迹。因为它在使用前没有任何标示,所以它只能用于父子进程之间。
创建与打开:int pipe(int fd[2]) 若成功则返回0,失败返回-1。fd[0]代表读, fd[1]代表写。
读:read(fd[]0],buff,size);
写:write(fd[1],buff,len);
关闭:close(fd[1]); close(fd[0]);
使用:int arr[2]; pipe(arr);
需要注意的是:管道都是半双工通讯, 无名管道创建后,父进程在 fork 产生子进程后,两个进程分别有一对读写,要在父子进程分别关闭读或写。
与上面相同的例题,用无名管道来做:
void main(){ int fd[2] = {0}; pipe(fd); pid_t pid = fork(); if(pid == 0) { while(1) { close(fd[0]); printf("please input:"); fflush(stdout); fgets(buff,127,stdin); write(fd[1],buff,strlen(buff)-1); if(strncmp(buff,"end",3) == 0) { break; } } } else { close(fd[1]); while(1) { int count = 0; read(fd[0],buff,127); if(strncmp(buff,"end",3) == 0) { break; } count += strlen(buff); printf("%d\n",count); } } close(fd[0]); close(fd[1]);}
- 进程间通信-管道(有名管道和无名管道)
- 进程间通信——管道(有名管道、无名管道)
- 进程间通信(无名管道,有名管道,共享内存)
- 【进程通信】无名管道 and 有名管道
- 经典进程间通信之无名管道和有名管道
- Linux进程间通信—无名管道和命名管道
- Linux进程间通信(一)之无名管道(PIPE)和有名管道(FIFO)
- 进程间通信IPC之--无名管道(pipe)和有名管道(fifo)
- linux进程通信机制之无名管道&有名管道
- 有名管道&无名管道
- 管道——(1)有名管道和无名管道
- 进程守护+有名管道+无名管道
- 进程间通信——有名管道(FIFO)
- 进程间通讯——管道(有名管道)
- 进程间通信:无名管道
- 进程间通信--无名管道
- 进程间通信--无名管道
- 进程间通信无名管道
- window 安装MongoDB 出现的exception:connect failed 异常
- 五 SparkMLlib,R实战 SVD分析
- MyBatis框架学习
- 洛谷P1373 小a和uim之大逃离(DP)
- 171020 逆向-Reversing.kr(Multiplicative)
- 进程间通信——管道(有名管道、无名管道)
- 李开复——人工智能领域的中坚力量
- 【Leetcode】【python】Sort Colors
- -webkit-font-smoothing:antialiased;属性
- beego配置
- selenium之Cookie的应用-取消Case耦合,依赖关系
- Ubuntu sudo nopasswd方法
- vmware ubuntu 16.04 guest 修复不能桌面大小自动调整和从宿主机复制粘贴的问题
- 689. Maximum Sum of 3 Non-Overlapping Subarrays