我有一个父和子进程都计数到50,然后终止。父进程等待,直到子进程计数到50,然后退出。我已经编写了代码,但它将进入无限循环:
int main()
{
long int T_Child = 0, T_parent = 0;
pid_t procid = fork();
int T = 0;
if(procid < 0)
{
printf("\nFailed");
exit(0);
}
else if(procid == 0)
{//child
while(T_Child < 50)
{
printf("\nCHILD : %ld",T_Child);
delay(2);
T_Child++;
}
exit(1);
}
else if(procid > 0)
{//parent
while(T_parent < 50)
{
printf("\nPARENT : %ld",T_parent);
delay(2);
T_parent++;
}
while(T_Child < 50)
{//to ensure parent exits after child
delay(1);
}
exit(1);
}
return 0;
}
我是这个领域的新手。请帮忙!
答案 0 :(得分:2)
分叉与线程不同。 fork创建进程的副本。该
子进程中变量的值与
fork()
时父进程的变量。这意味着
子变量从父级继承值,但是更改了
父级无法看到子变量。
如果父母需要等待孩子退出,则必须致电
wait
or waitpid
。此外,如果父母需要从孩子,父母和孩子那里获得价值
应该相互通信,例如使用pipe。
以下代码显示了parant和child如何相互通信和 父母应如何等待孩子离开:
#include <unistd.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void)
{
int comm[2];
// create pipe
if(pipe(comm) < 0)
{
perror("Could not create pipe");
return 1;
}
pid_t pid = fork();
if(pid < 0)
{
perror("Could not fork");
close(comm[0]);
close(comm[1]);
return 1;
}
if(pid == 0)
{
// CHILD
// closing reading end of the pipe
close(comm[0]);
do_some_work();
int result = 50;
// write to the parant through the pipe
write(comm[1], &result, sizeof result);
// closing writing end
close(comm[1]);
exit(0);
}
// PARENT
// close writing end of pipe
close(comm[1]);
puts("Now waiting for the child to exit...");
// parent waits for child to exit
int child_status;
if(waitpid(pid, &child_status, 0) < 0)
{
perror("Could not wait");
close(comm[0]);
return 1;
}
// if child exited without any error
if(WIFEXITED(child_status) && WEXITSTATUS(child_status) == 0)
{
// read answer from the child
int answer;
read(comm[0], &answer, sizeof answer);
printf("Child answered with %d\n", answered);
}
// closing reading end of pipe
close(comm[0]);
return 0;
}
答案 1 :(得分:2)
子进程和父进程在不同的内存空间中运行。在fork()时,两个内存空间都具有相同的内容。
有一个名为写入时复制(CoW)的概念;了解它有用 -
Copy on Write是一种优化,其中设置了页表,以便父进程和子进程开始共享所有相同的内存,并且只有在需要时才复制任一进程写入的页面。
[上面是从我自己的答案复制到旧帖子中]
在你正在执行的程序中:
while(T_Child < 50)
{//to ensure parent exits after child
delay(1);
}
T_Child
在0
之前使用fork
初始化T_Child
。由于地址空间是分开的,当子进程修改T_Child
的值时,CoW会创建其页面的副本 - 但0
的父副本仍具有初始值T_Child
。父进程未对while
中的值进行任何更改。因此,T_Child < 50
循环条件while(T_Child < 50){..
将始终为真,循环将无限执行。
相反,您应该等待子进程使用waitpid系统调用退出。代替waitpid(procid,&status,0);
循环,你应该这样做:
accounts
这将使父进程等到子进程退出。