linux入门:进程间通信之匿名管道

本文详细介绍了匿名管道作为进程间通信的基本机制,包括其工作原理、使用步骤及四种常见的情况分析,帮助读者理解如何利用匿名管道进行进程间数据交换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

      管道(匿名管道)是一种最基本的IPC机制,由pipe函数创建。

1. 父进程调 用pipe开辟管道,得到两个文件描述符指向管道的两端。
2. 父进程调 用fork创建 子进程,那么子进程也有两个文件描述符指向同 一管道。
3.  父进程关闭管道读端, 子进程关闭管道写端。父进程可以往管道写, 子进程可以管道里读,管道是用环形队列实现的,数据从写端流入从读端流出,这样就实现了进程间通信。


匿名管道实现进程间通信有以下四种情况:
1.指向管道写端的文件描述符未关闭,持有管道写端的进程也未向管道中写入数据,这时有进程从管道读端读数据,那么管道中剩余的数据都被读取后,再次read会阻塞,直到管道中有数据可读了才会读取数据并返回。

代码:


结果:



2.如果所有指向管道写端的文件描述符都关闭了(管道写端的引用计数等于0), 而仍然有进程从管道的读端读数据,那么管道中剩余的数据都被读取后,再次read会返回0,就像读到 文件末尾 一样。

代码:


结果:



3.所有指向管道读端的文件描述符都关闭了,只是有进程向管道的写端write,那么该进程会受到信号SIGPIPE,通常会导致进程异常终止。

代码:


结果:



4.指向管道读端的文件描述符未关闭,而持有管道读端的进程也没有从管道中读取数据,这时有进程向管道写端写数据,那么当管道被写满时,再次write会阻塞,直到管道中有空位置了才再写入数据并返回。(类似情况1)


源代码:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>

int main()
{
	int mypipefd[2];
	int fd = pipe(mypipefd);   //创建管道
	if(fd < 0)    //管道创建失败
	{
		perror("pipe");
		return 2;
	}
	
	pid_t id = fork();    //创建子进程
	if(id < 0)
	{
		perror("fork");
		return 2;
	}
	else if(id == 0)
	{
		close(mypipefd[0]);  //关闭子进程的读功能
		int i = 0;
		char *msg = NULL;
		while(i < 10)
		{
			msg = "hello bit";
			write(mypipefd[1],msg,strlen(msg)+1);  //子进程写
			sleep(1);
			i++;
		}
		close(mypipefd[1]);   //发送完毕子进程关闭写功能
		exit(1);
	}
	else
	{
		close(mypipefd[1]);    //父进程关闭写功能
		char _msg[128];
		int j = 0;
		while(j < 10)
		{
			ssize_t _s = read(mypipefd[0],_msg,sizeof(_msg)-1);//父进程读
			if(_s > 0)
			{
				_msg[_s] = '\0';
				printf("child->father: %s\n",_msg);
			}
			else if(_s == 0)  //读到了文件结尾(指向管道写端的文件描述符关闭)
				 //仍然有进程从管道的读端读数据,管道中剩余数据被读完则返回0
			{
				printf("pipe write is close\n");
				break;
			}
			j++;
		}
		close(mypipefd[0]);   //读完毕父进程关闭读功能

		int status = 0;
		pid_t ret = waitpid(id,&status,0);   
		if(ret < 0)
		{
			perror("wait");
		}
		else
		{
			printf("exit code: %d, signal: %d\n",(status>>8)&0xff, status&0xff);
		}
	}
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值