我试图找出父子进程的行为。 以下是我的代码
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(void)
{
int i,j,cnt=0;
int pid,present_pid;
int a[10];
for(i=0; i<10; i++) {
a[i] = i;
}
i = 0;
j = 5;
present_pid = getpid();
printf("Now in process %d\n",getpid());
printf("\n*******************before fork******************\n");
for(i=0;i<10;i++) {
printf(" %d",a[i]);
}
printf("\n*******************before fork******************\n");
int ret = fork();
if(ret == 0) {
printf("\n*******************after fork******************\n");
printf("Now in process %d\n",getpid());
printf("Child Process created");
for(i=0; i<5; i++) {
a[i]= +1;
i++;
}
}
else if(ret > 0) {
printf("\nNow in process %d\n",getpid());
for(j=5; j<10; j++) {
a[j] = +1;
j++;
}
wait();
}
for(i=0;i<10;i++) {
printf(" %d",a[i]);
}
return 0;
}
这是程序的输出
Now in process 12248
*******************before fork******************
0 1 2 3 4 5 6 7 8 9
*******************before fork******************
*******************after fork******************
Now in process 12249
Child Process created 1 1 3 3 5 5 6 7 8 9
Now in process 12248
0 1 2 3 4 6 6 8 8
因此,最初只有一个进程12248,它会分叉另一个进程(12249)。现在这两个过程都是并行的(如果我错了,请纠正我)。理想情况下,孩子应该将 a 的内容添加1 仅限于前半部分,而父级应该对第二部分执行相同操作。但正如您所看到的那样,输出并不像预期的那样。请提出建议..
答案 0 :(得分:3)
由fork
创建的进程是一个真正重量级的操作系统进程,而不仅仅是一个轻量级的线程!创建的进程不会与分叉的进程共享任何内存。相反,内存被复制(懒惰,所谓的写时复制),所以你现在实际上有两个数组a
,每个进程写入他自己的a
副本。
答案 1 :(得分:1)
您的代码中有2个小错误。通常我们甚至都没有注意到它们的存在。
a[i]= +1;
哦,亲爱的。我想你想写a[i] += 1
或a[i]++
。i++
和j++
。 for
循环已为您完成此操作。纠正它们,你会得到你期望的答案。
答案 2 :(得分:0)
首先对代码进行一些更改
printf("Now in process %d\n",getpid());
printf("Child Process created");
for(i=0; i<5; i++)
{
--> a[i]+= 1;
--> // i++; //comment this line you are jumping 2 steps in this loop
}
每当你执行fork()调用时,都会为子进程创建进程地址空间的精确副本,并且在fork()调用之后将程序计数器设置为该行
在你的案例之后
int ret = fork();
Program Counter--> if(ret == 0)
{
下,
Now both the process run parallel
是父进程并行运行但在执行完成后等待来自子进程的SIGCHLD
信号。
如果子进程返回SIGCHLD信号但父进程尚未收到(即父进程处于等待状态),则子进程被称为ZOMBIE
进程。
如果父进程突然中止且子进程仍在运行(或处于READY
状态),则子进程称为ORPHAN
进程。在这种情况下,名为init
的进程负责收集子进程的状态。
最后,程序流程。 父进程最初运行。
int ret = fork();//A child process is created
然后此代码在子进程中执行
if(ret == 0)
{
printf("\n*******************after fork******************\n");
printf("Now in process %d\n",getpid());
printf("Child Process created");
for(i=0; i<5; i++)
{
a[i] += 1;
//i++;
}
}
else if(ret > 0)//this condition is false in child process
{
// rest of code
}
//最后这是优秀的
for(i=0;i<10;i++)
{
printf(" %d",a[i]);
}
return 0;
then child process returns SIGCHLD signal
以下代码在父进程中执行
else if(ret > 0)//this is true for parent process
{
printf("\nNow in process %d\n",getpid());
for(j=5; j<10; j++)
{
a[j] = +1;
j++;
}
wait();
}
for(i=0;i<10;i++)
{
printf(" %d",a[i]);
}
return 0;
}
注意:父进程也返回SIGCHLD信号,此信号由init
进程收集
每当生成一个新进程时,默认情况下是init
进程的子进程