另外,如果我在进程之间创建和通信,我如何强制父进程“等待”所有进程完成其工作,因为wait()或waitpid()等待第一个完成的进程,但我需要等待它们.这是另一个问题.
谢谢…
解决方法
ls | grep foo | sort | uniq
有一些关于Unix编程的优秀介绍性文本,其中通过本书实现了一个简单的shell. shell的任务之一是重定向.其中一本书是Michael K. Johnson和Erik W. Troan的“Linux应用程序编程”.
该书的主页:http://ladweb.net/
要为N个进程构建重定向链,您需要N-1个管道.对于每个重定向,您使用管道(int fds [2])系统调用创建管道.在fork()之后,但在执行之前使用dup2(int from,int to)将管道的末端“连接”到标准输入(0)或每个进程的标准输出.这是一个过于简化的代码,没有错误检查:
int pipe_A[2]; int pipe_B[2]; pipe(pipe_A); pipe(pipe_B); pid_t pid_A,pid_B,pid_C; if( !(pid_A = fork()) ) { dup2(pipe_A[1],1); /* redirect standard output to pipe_A write end */ execv(...); } if( !(pid_B = fork()) ) { dup2(pipe_A[0],0); /* redirect standard input to pipe_A read end */ dup2(pipe_B[1],1); /* redirect standard output to pipe_B write end */ execv(...); } if( !(pid_C = fork()) ) { dup2(pipe_B[0],0); /* redirect standard input to pipe_B read end */ execv(...); }
请注意,如果管道的数组索引用于标准输入/输出文件描述符(如果它们用于stdio重定向),则会选择它们.这种选择并非随意.
当然,您可以将管道连接到任何文件描述符(例如,有些应用程序,希望它们的父项打开,比如fd 3和4,连接到管道),大多数shell也直接支持这个(例如1>& 3将stdout重定向到fd 3).然而,pipe(int fds [2])的数组索引当然是0和1.我只是告诉这个,因为我有一些货物狂热编程的学生,他们无意识地将目标fds用于管道系统调用阵列.
等待所有孩子完成使用waitpid(-1,NULL,0) – 我认为这是我的前回答者的意思-1,这意味着:等待所有子进程完成.另一种选择是在一个循环中调用wait(),它将返回刚刚终止的子进程的pid.如果再次调用并且仍然有一个孩子在运行,它将再次阻止.如果没有孩子,它将返回-1;我更喜欢waitpid解决方案.