我试图在 fork() 之后向孩子发送一些东西,我已经设置了 dup2 来重定向孩子的输出。但看起来它没有得到流。更进一步,我如何从孩子那里得到输出。该文件是一个外部可执行文件,它只是打印文本但没有显示。请问有什么帮助吗?
3 回答
您使用
pipe
不正确,因为它只需要调用一次(RTM)。你打错电话了
calloc
。利用calloc (100, sizeof (char))
不要将常量字符串分配给动态分配的内存部分。改为使用
char message[] = "sent from parent"
。这种方式也是有益的,因为您可以使用sizeof
inwrite
而不是100
. 这也可能导致分段错误,因为内存中的区域"sent from parent"
不是100
字节长。使用
execv
而不是execlp
. 你不需要使用execlp
一个问题是您调用pipe
了两次,您应该调用一次,如下所示:
if(pipe(tmpFd) == 0)
{
//now do fork
}
或者如果你想创建两个管道,你应该创建另一个变量,tmpFd2
这样你就可以这样做:
if(pipe(tmpFd) == 0 && pipe(tmpFd2) == 0)
{
/*
parent can write to tmpFd[1] and child can read from tmpFd[0]
child can write to tmpFd2[0] and parent can read from tmpFd2[1]
*/
}
现在您应该将两个文件描述符(tmpFd
和tmpFd2
)作为参数(argv
)传递给 socond 程序。
这样孩子就可以和父母交流了。
这是一个孩子和父母如何沟通的例子:
int main()
{
char buffer[1024];
const char child_data[] = "child says hello";
const char parent_data[] = "parent says hello";
if(pipe(tmpFd) == 0 && pipe(tmpFd2) == 0)
{
if(fork() == (pid_t)0)
{
printf("child.\n");
write(tmpFd[1], child_data, strlen(child_data));
read(tmpFd2[0], buffer, 100);
printf("child read: %s\n" , buffer);
}
else
{
printf("parent.\n");
write(tmpFd2[1], parent_data, strlen(parent_data));
read(tmpFd[0], buffer, 100);
printf("parent read: %s\n" , buffer);
}
}
else
{
printf("pipe failed.\n");
}
return 0;
}
这个例子没有使用exec
,但它给了你这个想法。
there are couple of problem in your code.. Basics of pipe, fork are missing here.
我建议首先清除您的管道和叉子知识。
为这个问题首先抛出这个例子http://www.cim.mcgill.ca/~franco/OpSys-304-427/messages/node92.html
see below comments from #Comment# tag
void createChildren(void){
struct AgentInfo *child= head; //#Comment1# I am assuming you are getting correct child here
int tmpFd[2];
int parentWrite = tmpFd[OUT]; //#Comment2# you dont need to take this in another variable. Till now its garbage value as you have not passed it threw pipe function. It will initialise inside pipe function
int parentRead = tmpFd[IN];//#Comment3# same as above
while(child !=NULL){
pipe(tmpFd);
child->childRead = tmpFd[IN];
pipe(tmpFd); //#Comment4# prev pipe var has been overwriten. you just need one pipe to transfer data from parent to child or vice versa
// 在管道中,父 fd tmpFd[1] 用于写入 fd,tmpFd[0] 用于读取 // 对于子 fd tmpFd[0] 用于写入,tmpFd[1] 用于读取
child->childWrite = tmpFd[OUT];
child->agentPid = fork();
char* message = calloc(100,sizeof(char*)); //#Comment5# create this element before fork as it will create twice if you allocate it after fork
message = "sent from parent\n"; //#Comment6# This is highly misunderstanding of memory allocation if you want to use same memory as you have allocated in calloc than use strcpy function.
//constant string will allocate memory once again
if(child->agentPid<0){
exit(-1);
}
if(child->agentPid == 0){ //#Comment8# this means its parent code. For child it will be child->agentPid > 0 write you child code there. after this whoile code is totally wrong
printf("in the child\n");
dup2(child->childWrite,STDOUT_FILENO); //#Comment7# Why you are involving STDOUT/IN heare as you just want to transfer data bet parent child. you can use tmpFd for this directly
dup2(child ->childRead,STDIN_FILENO);
/*fwrite(message, 100, 1,stdin);*/
write(STDIN_FILENO, message,100);
close(child->childRead);
close(child->childWrite);
/*close(parentWrite);*/
/*close(parentRead);*/
execlp(child->fileName,child->fileName,NULL);
/*error handled here and exit status*/
}else{
/*write(child->childRead,message,100);*/
/*read(parentRead,message,100);*/
char* temp = calloc(100,sizeof(char*));
printf("in parent\n");
read(child->childWrite, temp,100);
printf("%s", temp);
child = child->next;
}
}
}