c-多个子进程向父进程写入用popen执行的unix命令的结果



我必须编写一个C代码:

  • 接受'n'命令行参数(unix命令)
  • 对于每个参数,主程序启动两个子进程
  • 每个子进程将使用popen以随机延迟执行unix命令(args[i]),然后将答案发送给父进程父进程将只打印收到的前n/2个响应
  • 父进程和子进程之间的通信只能使用管道通道

我已经编写了以下源代码:

#include <stdio.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <wait.h>
#include <time.h>
#include <string.h>
#include <errno.h>
#define DIM 100
int main(int argc, char *args)
{
int t, nrR=argc-1,f,p[2],prID,d;
FILE *fd1, *fd2;
//PIPE channel creation
if(pipe(p)<0)
{
perror("PIPE channel creation error!");
exit(1);
}
for(i=1;i<argc;i++)
{
d=strlen(args[i]);
if((f=fork())==0)
{  //FIRST CHILD PROCESS
char *buffer = malloc(DIM*sizeof(char));
//The child process will only write to the parent process
close(p[0]);
//Delay the process execution
srand(time(NULL));
int s=rand()%2;
sleep(s);
fd1 = popen(args[i],"r");
//Writing the PID to the parent process
prID=getpid();
if(write(p[1],&prID,sizeof(int))!=sizeof(int))
{
perror("PIPE writing error!");
exit(3);
}
//Writing the command string length
if(write(p[1],&d,sizeof(int))!=sizeof(int))
{
perror("PIPE writing error!");
exit(3);
}
//Writing the command string
if(write(p[1],args[i],sizeof(args[i]))!=sizeof(args[i]))
{
perror("PIPE writing error!");
exit(3);
}
//Writing the command output result string
while(fread(buffer,DIM,1,fd1)>0)
{
if(write(p[1],buffer,sizeof(buffer))!=sizeof(buffer))
{
perror("PIPE writing error!");
exit(3);
}
}
free(buffer);  
pclose(fd1);
exit(i+1);
}
else if((f=fork())==0)
{  //SECOND CHILD PROCESS
char *buffer = malloc(DIM*sizeof(char));
//The child process will only write to the parent process
close(p[0]);
//Delay the process execution
srand(time(NULL));
int s=rand()%2;
sleep(s);
fd2 = popen(args[i],"r");
//Writing the PID to the parent process
prID=getpid();
if(write(p[1],&prID,sizeof(int))!=sizeof(int))
{
perror("PIPE writing error!");
exit(3);
}
//Writing the command string length
if(write(p[1],&d,sizeof(int))!=sizeof(int))
{
perror("PIPE writing error!");
exit(3);
}
//Writing the command string
if(write(p[1],args[i],sizeof(args[i]))!=sizeof(args[i]))
{
perror("PIPE writing error!");
exit(3);
}
//Writing the command output result string
while(fread(buffer,DIM,1,fd2)>0)
{
if(write(p[1],buffer,sizeof(buffer))!=sizeof(buffer))
{
perror("PIPE writing error!");
exit(3);
}
}
free(buffer);  
pclose(fd2);
exit(i+2);
} 
}
if(f>0)
{
//Parent process behavior
close(p[1]); //The parent process will not write to the child processes
for(i=0;i<nrR;i++)
{
//we will read and print only the first 'n' responses received through the pipe channel from the child processes
waitpid(-1,NULL,0);
char *cmd,*buffer;
//Read the pid of the child process
if(read(p[0],&prID,sizeof(int))!=sizeof(int))
{
perror("PIPE reading error!")
exit(2);
}
//Read the command string length
if(read(p[0],&d,sizeof(int))!=sizeof(int))
{
perror("PIPE reading error!")
exit(2);
}
//Read the command
cmd = malloc(d*sizeof(char));
if(read(p[0],cmd,sizeof(cmd))!=sizeof(cmd))
{
perror("PIPE reading error!")
exit(2);
}
printf("nProcess %d -> %s:n",prID,cmd);
//Read and print the unix command result
buffer = malloc(DIM*sizeof(char));
while(read(p[0],buffer,sizeof(buffer))>0)
{
printf("%s",buffer);
}
free(buffer);
free(cmd);
//Wait for other n/2 child processes to terminate
while(waitpid(-1,NULL,0)>0)
{
if(errno == ECHILD)
break;
}
}
}
return 0;
}

我的代码编译并运行;我试过用"ls"作为论据。程序没有显示预期的输出。我介绍了一些支票打印,并检测到以下问题:

  • 在子进程中,我无法读取fd1和fd2的整个"ls"输出
  • 父进程没有接收任何内容/没有正确接收通过管道从子进程发送的"ls"输出字符串(它正确接收子进程ID和命令名)

尝试在同一PIPE通道中写入(可能在同一时间)的多个子进程是否会导致问题?或者还有其他一些我没有想到的问题?

非常感谢。

每个子级都需要自己的管道返回父级,因此p应该是一个2d数组,p[child][file-id]。您在任何时候都不会试图收集命令数据,也不会访问与命令stdout相关的管道。您计划如何将命令输出发送回父级。你需要告诉父母有多少字节的文本,然后把它全部写出来可能是最好的解决方案。它允许您对一个缓冲区进行malloc,准备将其存储为字符串,并且它也可以是块读取,而不是一次一个字节,直到出现"\0">

最新更新