进程中的if和else

发布时间 2023-12-26 18:30:04作者: crayon's

进程互斥实验的时候遇到了一段代码没有看懂

#include <stdio.h>
#include <unistd.h>
int main( )
{
     int p1,p2,i;
     while((p1=fork( ))= = -1);       /*创建子进程p1*/
     if (p1= =0)
     {
          lockf(1,1,0);          /*加锁,这里第一个参数为stdout(标准输出设备的描述符)*/
          for(i=0;i<10;i++)
               printf("daughter %d\n",i);
     lockf(1,0,0);                     /*解锁*/
     }
     else
     {
          while((p2=fork( ))= =-1);  /*创建子进程p2*/
          if (p2= =0)
          {
               lockf(1,1,0);        /*加锁*/
               for(i=0;i<10;i++)
                    printf("son %d\n",i);
          lockf(1,0,0);            /*解锁*/
          }
          else
          {
               lockf(1,1,0);         /*加锁*/
               for(i=0;i<10;i++)
               printf(" parent %d\n",i);
               lockf(1,0,0);         /*解锁*/
          }
     }
}

这段代码执行的结果为(并不唯一)

daughter 0
daughter 1
...
daughter 9
...
parent 9

Q:为什么代码执行了if还能执行else?if else不应该是选择分支,只会执行一条吗?

1.首先懂得是如何子进程是如何创建的

使用fork() 函数进行进程的创建,会返回两个值,一个是向父进程返回子进程的PID,一个是向子进程返回0,子进程与父进程并发执行。

fork() 的返回值如下:
- 0:在子进程中,返回的是0,表示当前进程是子进程。
- \>0:在父进程中,返回的是子进程的id值
- -1:表示创建失败

fork执行后,子进程会得到:
- 进程表项和进程表示符
- 子进程继承父进程的所有文件
- 由核心创建的进程上下文
- 子进程执行(子进程的程序计数器是自己的,与父进程不同)

在代码中,首先父进程创建了一个子进程p1,然后给父进程的p1返回的是p1的pid,给子进程p1返回的p1是0,所以代码中的if语句在子进程中执行,而else语句在父进程中执行,else中的语句也如此,父进程继续创建子进程p2,fork给子进程p2返回0,给父进程返回子进程的pid,此时三个进程同时运行。

父进程继续执行else语句,而进程p1执行if语句,输出daught 0-9,进程p2也执行if 输出 son 0-9 ,父进程输出parent 0-9,由于使用了加锁,所以会对输出设备进行加锁,当一个进程在使用的时候,其他进程无法使用输出设备。

但是为什么输出顺序会改变?是由于操作系统的调度策略和进程的竞争情况决定的,看似p1要先于p2创建,但并不能表示p1的执行要优先与p2或父进程。

。。。个人理解。。