【发布时间】:2015-07-07 17:55:36
【问题描述】:
我必须编写一个 C 代码:
- 接受“n”个命令行参数(unix 命令)
- 对于每个参数,主程序启动两个子进程
- 每个子进程将随机延迟执行unix命令(args[i])并使用popen,然后将答案发送给父进程 父进程将仅打印收到的前 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 通道中写入(可能在同一时间)导致的问题?还是有其他一些我没有想到的问题?
非常感谢。
【问题讨论】: