![](/img/trans.png)
[英]Simple multiple child exec'd fork segfaulting when trying to read from stdout of child
[英]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.