簡體   English   中英

C從fork調用的多個exec讀取stdout

[英]C Read stdout from multiple exec called from fork

在下面的代碼中,進程創建一個子進程( fork() ),然后子進程通過調用exec()來替換它自己。 exec的stdout寫在管道而不是shell中。 然后父進程從管道中讀取exec寫入的內容while(read(pipefd [0],buffer,sizeof(buffer))!= 0)

有人可以告訴我如何做與上述完全相同的事情,但有N個子進程(如上所述用exec替換自己)。

int pipefd[2];
pipe(pipefd);

if (fork() == 0)
{
    close(pipefd[0]);    // close reading end in the child

    dup2(pipefd[1], 1);  // send stdout to the pipe
    dup2(pipefd[1], 2);  // send stderr to the pipe

    close(pipefd[1]);    // this descriptor is no longer needed

    exec(...);
}
else
{
    // parent

    char buffer[1024];

    close(pipefd[1]);  // close the write end of the pipe in the parent

    while (read(pipefd[0], buffer, sizeof(buffer)) != 0)
    {
    }
}

我找到了答案。 我創建了一個管道數組,以便進程不會覆蓋另一個進程的輸出。

這是我的代碼。 你發現有什么錯嗎?

#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>

#define N 10

int main(int argc, char *argv[]) {
    ssize_t readlen;
    int pipefd[N][2];
    int i;
    for (i = 0; i < N; i++) {
        pipe(pipefd[i]);
    }

    int pid = getpid();

    for (i = 0; i < N; i++) {
        if (fork() == 0) //The parent process will keep looping
        {

            close(pipefd[i][0]);    // close reading end in the child

            dup2(pipefd[i][1], 1);  // send stdout to the pipe
            dup2(pipefd[i][1], 2);  // send stderr to the pipe

            close(pipefd[i][1]);    // this descriptor is no longer needed

            char b[50];
            sprintf( b, "%d", i);

            execl("/bin/echo", "echo", b,NULL);


        }
    }

    if (pid == getpid()) {

        // parent

        char buffer[1024];

        for (i = 0; i < N; i++) {
            close(pipefd[i][1]);  // close the write end of the pipe in the parent

            while ((readlen=read(pipefd[i][0], buffer, sizeof(buffer))) != 0)
            {
                        buffer[readlen] = '\0';
            }

            printf("%s\n",buffer);

        }
    }


}

也許這段代碼可以完成這項工作:

const int N = 10; //Number of child processes
int pipefd[2];
pipe(pipefd);
int i;
for (i = 0; i < N; i++) {
    if (fork() == 0) //The parent process will keep looping
    {
        close(pipefd[0]);    // close reading end in the child

        dup2(pipefd[1], 1);  // send stdout to the pipe
        dup2(pipefd[1], 2);  // send stderr to the pipe

        close(pipefd[1]);    // this descriptor is no longer needed

        exec(...);
    }
}

// parent

char buffer[1024];

close(pipefd[1]);  // close the write end of the pipe in the parent

while (read(pipefd[0], buffer, sizeof(buffer)) != 0)
{
}

警告:輸出將混合。 如果您希望所有進程在不混合的情況下轉儲數據,那么您應該設法同步進程(例如,通過公共鎖)。

我認為您可以在文件系統的任何位置(如本地套接字)創建命名的chanel,並將所有接收的數據讀取到父進程。 因此,子進程必須將其獲取的數據寫入此通道。 它將是類似unix的架構。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM