[英]C in Unix: fork, waitpid and pipes
我的問題是關於如何控制與管道有關的進程執行,尤其是wait
/ waitpid
函數的實現。
當我對下面的命令創建一個管道ls | head -3
ls | head -3
,我執行以下操作:
head -3
命令,關閉孩子中管道的輸出端 ls
命令,關閉父級中管道的輸入端 我的問題: 基於此討論 ,我確實需要等待孩子完成執行,即head -3
的執行。 但是,如何/在何處實現waitpid
函數,使其與close[]
命令不沖突?
基於此出色的文字 ,說明如下:
如果父母希望從孩子那里接收數據,則應關閉fd1,然后孩子應關閉fd0。 如果父母希望將數據發送給孩子,則應關閉fd0,然后孩子應關閉fd1。 由於描述符是在父級和子級之間共享的,因此,我們始終應確保關閉無關的管道末端。 從技術上講,如果未顯式關閉管道不必要的末端,則EOF將永遠不會返回。
因此,子級必須在執行前等待父級完成管道。
我還看到了為管道的一個過程制作兩個叉子的示例。 就像我在《 APUE ch.8》副本中的描述一樣,這是否是避免僵屍進程的目的?
考慮以下代碼實現:
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
int main()
{
int pid, status;
int fd[2];
char *com1[2];
char *com2[3];
com1[0] = "ls";
com1[1] = NULL;
com2[0] = "head";
com2[1] = "-3";
com2[2] = NULL;
pipe(fd);
if((pid = fork()) == -1)
{
printf("fork error");
exit(1);
}
if(pid == 0)
{
/* Child process closes up output side of pipe */
dup2(fd[0], 0);
close(fd[1]);
execvp(com2[0], com2);
}
else
{
/* if(waitpid(0, WIFEXITED(&status), 0) != pid)
{
printf("wait error");
}
is this even needed here? */
/* Parent process closes up input side of pipe */
dup2(fd[1], 1);
close(fd[0]);
execvp(com1[0], com1);
}
exit(0);
}
我必須承認,我在StackExchange上瀏覽了許多類似的問題。 但是,幾乎所有這些內容都具有特定的內容。 我正在尋找的是原理的解釋和功能的組合。 感謝您的時間!
你們不能都想等孩子和高管。 所以你需要有兩個孩子。 有兩種常見的方法可以執行此操作:要么有一個父進程創建兩個直接子進程,然后可以/必須等待兩個進程; 或有一個自己創建第二個孩子的孩子,這樣父孩子只需要等待一個過程終止即可。
選項1 (繼承的管道)
pipe(pi);
pid1 = fork();
if (pid1==0) { // child1
// make redirections
exec("head"...);
}
pid2 = fork();
if (pid2==0) { // child2
// make redirections
exec("ls"...);
}
// parent process
// close unuseful pipe
waitpid(pid1...);
waitpid(pid2...);
選項2 (管道僅對相關過程可見)
pid1 = fork();
if (pid1==0) { // child
pipe(pi);
pid2 = fork();
if (pid2==0) { // gran child
// make redirections
exec("ls"...);
}
// make redirections
exec("head"...);
}
// parent process
waitpid(pid1...);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.