进程通信(管道)

1. 管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道; 

2. 只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程);

3. 单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中;

4. 数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。

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

int main()
{
	int pipe_fd[2];
	pid_t pid;
	char r_buf[100];
	char w_buf[4];
	char * p_wbuf;
	int r_num;
	int cmd;
	memset(r_buf, 0, sizeof(r_buf));
	memset(w_buf, 0, sizeof(r_buf));
	p_wbuf = w_buf;
	if (pipe(pipe_fd) < 0) {
		printf("pipe create error\n");
		return -1;
	}
	if ((pid = fork()) == 0) {
		close(pipe_fd[1]);
		sleep(3); /* 确保父进程关闭写端 */
		r_num = read(pipe_fd[0], r_buf, 100);
		printf( "read num is %d the data read from the pipe is %d\n", r_num, atoi(r_buf));
		close(pipe_fd[0]);
		exit(0);
	} else if (pid > 0) {
		close(pipe_fd[0]); /* read */
		strcpy(w_buf, "111");
		if (write(pipe_fd[1], w_buf, 4) != -1)
			printf("parent write over \n");
		/* 管道写端关闭后,写入的数据将一直存在,直到读出为止 */
		close(pipe_fd[1]); /* write */
		printf("parent close fd[1] over\n");
		sleep(10);
	}
	return 0;
}

对管道的写规则的验证1:写端对读端存在的依赖性

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
int main()
{
	int pipe_fd[2];
	pid_t pid;
	char r_buf[4];
	char * w_buf;
	int writenum;
	int cmd;
	memset(r_buf, 0, sizeof(r_buf));
	if (pipe(pipe_fd) < 0) {
		printf("pipe create error\n");
		return -1;
	}
	if ((pid = fork()) == 0) {
		close(pipe_fd[0]);
		close(pipe_fd[1]);
		sleep(10); 
		exit(0);
	} else if (pid > 0) {
		sleep(1); /* 等待子进程完成关闭读端的操作 */
		close(pipe_fd[0]); /* write */
		w_buf = "111";
		if ((writenum = write(pipe_fd[1], w_buf , 4)) == -1)
			printf("write to pipe error\n");
		else 
			printf("the bytes write to pipe is %d\n", writenum);
		close(pipe_fd[1]);
	}
	return 0;
}

则输出结果为: Broken pipe,原因就是该管道以及它的所有fork()产物的读端都已经被关闭。如果在父进程中保留读端,即在写完pipe后,再关闭父进程的读端,也会正常写入pipe,读者可自己验证一下该结论。因此,在向管道写入数据时,至少应该存在某一个进程,其中管道读端没有被关闭,否则就会出现上述错误(管道断裂,进程收到了SIGPIPE信号,默认动作是进程终止)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值