网站首页 > 技术文章 正文
概念
管道,是一种把两个进程之间的标准输入和输出连接的起来的一种通信机制,它是单向数据流,一个进程写入管道的所有数据都由内核定向到另一个进程中,另一个进程就可以从管道中读取数据。
管道可以分为匿名管道和命名管道。通常所说的管道是匿名管道,除非指明命名管道。
在Linux系统中,管道比较常用,如 ls -l | grep string 就使用了管道技术。
特点
- 半双工通信的(即数据只能在一个方向上流动),具有固定的读端(fd[0]为读端)和写端(fd[1]为写端)。
- 它只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)。
- 它可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。
函数原型
1) 头文件: #include<unistd.h>
2) 定义函数: int pipe(int filedes[2]);
3) 函数说明: pipe()会创建管道,并将文件描写叙述词由參数filedes数组返回。
filedes[0]为管道的读取端
filedes[1为管道的写入端。
4) 返回值: 若成功则返回零,否则返回-1,错误原因存于errno中。
原理
匿名管道,用于具有亲缘关系的进程间通信,即父子进程间通信。
1、首先,在主进程(父进程)中创建匿名管道,
2、然后,在主进程调用fork创建子进程,这时父子进程同时拥有了管道返回的文件描述符。
3、在父进程(fork 返回值大于0)中,关闭读端(fd[0]),写数据到写端(fd[1]),或者关闭写端 (fd[1]),从读端(fd[0])阻塞读取数据
4、在子进程(fork返回值==0)中,关闭写端(fd[1]),从读端(fd[0])阻塞读取数据,或者关闭读端 (fd[0]),写数据到写端(fd[1])。
代码示例
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int main( int agrc, char **argv )
{
int fds[2]; /* fds[0]read */
pid_t pid;
int ret = pipe( fds );
if ( ret < 0 )
{
printf( "create pipe error\n" );
exit( -1 );
}
ret = fork();
if ( ret < 0 )
{
printf( "fork error!\n" );
exit( -1 );
}
else if ( ret > 0 ) /* 父进程 */
{
/* 关闭读端 */
close( fds[0] );
/* 写数据 */
char data[] = "hello world\n";
write( fds[1], data, strlen( data ) + 1 );
}else { /* 子进程 */
/* 关闭写 */
close( fds[1] );
char buff[20] = { 0 };
/* 读数据 */
read( fds[0], buff, 20 );
printf( "child fork read:%s", buff );
}
return(0);
}
总结
1、匿名管道适用于具有亲缘关系的进程间通信。
2、匿名管道是数据是流向是单向的,进程在写数据时要关闭读端(fd[0]),在读数据是要关闭写端(fd[1])
3、fork 函数返回值大于0,处理父进程逻辑;等于0 ,处理子进程逻辑;小于0创建进程错误。
猜你喜欢
- 2024-10-01 原来“进程间通信”是这么回事! 什么叫进程间通信
- 2024-10-01 如何轻松掌握linux内核进程间通信方法
- 2024-10-01 Linux进程间通信(四) - 共享内存 linux共享内存休眠
- 2024-10-01 linux中的进程间通信-管道 linux进程间通信
- 2024-10-01 Linux讲解 进程间通信 命名管道 徐教头讲解象棋合集
- 2024-10-01 linux下进程通信的几种方式 linux系统下进程间通信
- 2024-10-01 Linux进程间通信——内存共享映射
- 2024-10-01 c/c++ Linux 进程间通信------共享内存
- 2024-10-01 Linux系统编程之进程间通信方式:消息队列
- 2024-10-01 如何使两个无关的进程进行通信? 两个进程间的通信
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)