Linux -- 进程间通信之管道

管道是Linux里的一种文件类型,同时也是Linux系统下进程间通信的一种方式


创建一个管道文件有两种方式:

1.  Shell 下命令 mkfifo + filename,即创建一个有名管道

2.  C语言里调用 pipe( ) 函数,创建一个无名管道


有名管道 / 无名管道 

区别:

1.  有名管道在程序外部使用 mkfifo 命令生成,无名管道在程序内部调用 pipe( ) 函数创建;

2.  顾名思义,有名管道有文件名,无名管道没有文件名;

3.  有名管道生成后直到删除都存在,无名管道在程序退出时则生命周期结束;

4.  有名管道可以在任意两个进程间传输数据,无名管道只能在父子进程间传输数据;

*有名/无名管道都是半双工

(只能从一端向另一端发送数据,输入端与输出端在打开管道时是固定的)


管道文件的特性:

1.  打开管道必须有两端(两个进程)同时打开一个管道,分别为读(r)和写(w);读取端负责从管道中读取数据,写入端负责向管道中输入数据;

2.  当读端关闭,写端会收到信号,终止程序;当写端关闭,读端不再进入阻塞;

3.  管道文件的大小始终为0,打开管道文件时,在内存中为其分配空间,管道关闭后数据消失;Linux默认PIPE_SIZE(一个管道最大存储大小)为64k,PIPE_BUF(管道缓冲区)为4k;当对管道进行 write 操作时,若此时有多个进程同时写入一个管道,且写入的字节大小超过PIPE_BUF,则写操作的数据有可能相互穿插。



管道文件的内存空间有两个指针 head / tail ,head指针随读取数据向后移动,tail指针随写入数据向后移动,当指针到文件尾时,会造成读阻塞 (读取结束)/ 写阻塞(空间已满)


*注意*

当我们调用 pipe( ) 创建无名管道后 fork( ) 以实现父子进程间通信,此时 pipe( ) 生成的两个 r / w 描述符引用都会加一,在父子进程中同时存在 r / w 两个描述符,此时应当在父子进程中分别 close 不用的描述符,使 r / w 端只存在一个引用,这样父子进程间通信时可以正常读写响应。


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>

int main()
{	
	char buff[128] = {0};
	pid_t pid;
	int pipefd[2];
	pipe(pipefd);					// creat & open a fifo file

	pid = fork();
	if(pid == -1)
	{
		printf("fork error\n");
		exit(0);
	}
	else if(pid == 0)				// chid process
	{
		close(pipefd[1]);			// close 'w' 
		
		if( read(pipefd[0],buff,128) <= 0)
		{
			printf("read error\n");
			exit(0);
		}
		printf("child : %s\n",buff);
	}
	else						// parent process
	{
		close(pipefd[0]);			// close 'r' fd
		
		printf("input: ");
		fflush(stdout);
		gets(buff);
		if( write(pipefd[1],buff,127) <= 0)
		{
			printf("write error\n");
			exit(0);
		}
	}
	
	close(pipefd[0]);
	close(pipefd[1]);
	
	exit(0);
}



  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值