APUE读书笔记——高级进程通信(管道)

假设我们要将一个文件的数据,通过more程序来显示

但不希望建立临时文件, 即先复制整个文件,再用more来展示

我们可以把文件的数据塞入一个管道,  more程序(由子进程excel启动)读这些数据,并显示在屏幕上

和直接more一个文件有啥区别???

#include "apue.h"
#include <sys/wait.h>
#define DEF_PAGER "/bin/more"
int main(int argc, char *argv[]){
	int n;
	int fd[2];
	pid_t pid;
	char *paper, *argv0;
	char line[MAXLINE];
	FILE *fp;
	if(argc != 2)
		err_quit("usage: a.out <pathname>");
	if((fp = fopen(argv[1], "r")) == NULL)
		err_sys("can't open %s", argv[1]);
	if(pipe(fd) < 0)
		err_sys("pipe error");
	if((pid = fork()) < 0)
		err_sys("pipe error");
	else if(pid > 0){  //parent!
		close(fd[0]);  //关闭读管道端(即管道流向父进程的那段)
		while(fgets(line, MAXLINE, fp) != NULL){
			n = strlen(line);
			//每次读一行,写入管道中
			if(write(fd[1], line ,n) != n)
				err_sys("write error to pipe");
		}
		if(ferror(fp))
			err_sys("fgets error");
		close(fd[1]);
		if(waitpid(pid, NULL, 0) < 0)
			err_sys("waitpid error");
		exit(0);
	}else {
		//子进程,则关闭子进程到管道的那一端
		//故子进程负责读管道
		close(fd[1]);
		if(fd[0] != STDIN_FILENO){
			//重定向,故标准输入成为读管道端
			//从apue画的图上看,描述符0和描述符fd0都指向了管道的读端
			if(dup2(fd[0], STDIN_FILENO) != STDIN_FILENO){
				err_sys("dup2 error to stdin");
			}
			//关闭fd0,则此时只有描述符0指向读管道端。
			//即不再是通过fd0与管道联系,而是标准输入与管道联系
			//即不再是fd0读管道,而是子进程的标准输入读管道。
			close(fd[0]);
		}
		if((paper = getenv("PAGER")) == NULL)
			paper = DEF_PAGER;
		if((argv0 = strrchr(paper, '/')) != NULL)
			argv0++;
		else argv0 = paper;
		//启用./bin/more
		//此时,我们可以在终端上输入命令,传给more进程即分页读进程
		execl(paper, argv0, (char *)0);
	}
}



popen直接将fork和建立单向管道合并在了一起,并且支持缓冲区,即返回文件指针。

这个是大写转小写chengxu

#include "apue.h"
#include <ctype.h>
int main(int argc, char *argv[]){
	int c;
	while( (c = getchar() != EOF)){
		if (isupper(c))
			c = tolower(c);
		if (putchar(c) == EOF)
			err_sys("output error");
		if ( c == '\n')
			fflush(stdout);
	}
	exit(0);
}





#include "apue.h"
#include <sys/wait.h>
int main(int argc, char *argv[]){
	char line[MAXLINE];
	FILE *fpin;
	
	//fork了一个子进程myuclc,且现在会读子进程的标准输出
	//fpin就是可以读 那个子进程输出 的文件指针
	if((fpin = popen("myuclc", "r")) == NULL)
		err_sys("popen error");
	for(;;){
		fputs("prompt> ", stdout);
		fflush(stdout);  //洗刷标准输出缓冲区,即直接把prompt输出
		//不断读fpin那传来的行
		//那一边每读到一次'\n',就会洗刷缓冲,把一行的内容发送过来
		if(fgets(line, MAXLINE, fpin) == NULL)
			break;
		if(fputs(line, stdout) == EOF)
			err_sys("fputs error to pipe");
	}
	if(pclose(fpin) == -1)
		err_sys("pclose error");
	putchar("\n");
	exit(0);
}

通过popen,建立了一个过滤程序,      主程序给屏幕输出提示, 我们从屏幕输入一行字符串,字符串传给过滤程序,过滤程序处理后发送给主程序,主程序输出

注意要经常洗刷缓冲区,即把他输出出来。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值