15.4 协同进程
(1)概念
过滤程序:指从标准输入中读取数据,向标准输出写数据的程序(比如管道产生两个程序)。
协同进程:某个过滤程序1既能产生过滤程序2的输入,又能读取读取过滤程序2的输出时,过滤程序1就为协同进程(coprocess)
注:1.管道就是协同进程的例子。
2.当子进程为过滤程序时,父进程产生子进程的输入,同时父进程又读取子进程的输入,这时子进程程序为协同进程。
3.popen只提供连接到另一个进程的标准输入或标准输出的一个单向管道,而协同进程则有连接到另一个进程的两个单向通道。
(2)协同进程的示例
1.进程创建两个管道:一个是协同进程的标准输入,另一个是协同进程的标准输出
2.fork一个子进程
3.父进程从子进程那儿读取数据,父进程对数据处理后将数据输出到标准输出。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <sys/wait.h>
#include <sys/acct.h>
#include <errno.h>
#include <sys/times.h>
#include <pthread.h>
#include <signal.h>
#define STRING_MAXLEN 50
/* 测试目的:
(2)协同进程的示例
1.进程创建两个管道:一个是协同进程的标准输入,另一个是协同进程的标准输出
2.fork一个子进程
3.父进程从子进程的标准输入中读取数据,父进程对数据处理后将输出到子进程的标准输出。
测试结果:
123456 // 子进程从终端输入的
cw: 123456 // 子进程向管道1写入的
pr: 123456 // 父进程从管道1中读出的
pw: 3456 // 父进程向管道2写入的
cr: 3456 // 子进程从管道2读出的
*/
int main()
{
int fds1[2]={-1}; // 子进程写,父进程读
int fds2[2]={-1}; // 子进程读,父进程写
pid_t pid;
char wbuf[STRING_MAXLEN+1]={0};
char rbuf[STRING_MAXLEN+1]={0};
// creat pipes
assert(0 == pipe(fds1));
assert(0 == pipe(fds2));
// 创建子进程
if (0 > (pid = fork())){
perror("fork\n");
}
else if(0 == (pid = fork())){ // 子进程从标准输入中获取数据,写给父进程; 读取父进程的数据并输出到标准输出
close(fds1[0]); // 关闭读端
close(fds2[1]); // 关闭写端
bzero(rbuf, STRING_MAXLEN);
bzero(wbuf, STRING_MAXLEN);
scanf("%s", wbuf);
//rbuf[STRING_MAXLEN]='\0';
printf("cw: %s\n",wbuf);
write(fds1[1], wbuf, STRING_MAXLEN);
read(fds2[0], rbuf, STRING_MAXLEN);
printf("cr: %s\n", rbuf);
}
else { // 父进程读取子进程的标准输入文件,进过处理后从子进程的标准输出中输出
close(fds1[1]); // 关闭写端
close(fds2[0]); // 关闭读端
bzero(rbuf, STRING_MAXLEN);
bzero(wbuf, STRING_MAXLEN);
read(fds1[0], rbuf, STRING_MAXLEN);
printf("pr: %s\n", rbuf);
memmove(wbuf,rbuf+2, STRING_MAXLEN-2); // 去掉前两个字符
printf("pw: %s\n", wbuf);
write(fds2[1], wbuf, STRING_MAXLEN-2);
}
pause();
return 0;
}