开源鸿蒙测试fork/waitpid

开源鸿蒙Fork和Waitpid测试

前言

最近做项目需要用到多进程部分,并在不同平台进行测试,现将结果记录如下:

接口介绍

  • fork

    #include 
    //creates a new process by duplicating the calling process.
    //The new process is referred to as the child process.  The calling
    //process is referred to as the parent process.
    //The child process and the parent process run in separate memory
    //spaces.  At the time of fork() both memory spaces have the same
    //content.  Memory writes, file mappings (mmap(2)), and unmappings
    //(munmap(2)) performed by one of the processes do not affect the
    //other.
    //Return
    //On success, the PID of the child process is returned in the
    //parent, and 0 is returned in the child.  On failure, -1 is
    //returned in the parent, no child process is created, and errno is
    //set to indicate the error.
    
    pid_t fork(void);
    
  • wait

    #include 
    #include 
    //The wait() system call suspends execution of the calling thread
    //until one of its children terminates.  The call wait(&wstatus) is
    //equivalent to:waitpid(-1, &wstatus, 0);
    //Return
    //on success, returns the process ID of the terminated
    //child; on failure, -1 is returned.
    
    pid_t wait(int *status);
    
  • waitpid

    #include 
    #include 
    //The waitpid() system call suspends execution of the calling
    //thread until a child specified by pid argument has changed state.
    //By default, waitpid() waits only for terminated children, but
    //this behavior is modifiable via the options argument, as
    //described below.
    //The value of pid can be:
    //  < -1   meaning wait for any child process whose process group ID
    //         is equal to the absolute value of pid.
    //  -1     meaning wait for any child process.
    //  0      meaning wait for any child process whose process group ID
    //         is equal to that of the calling process at the time of the
    //         call to waitpid().
    //  > 0    meaning wait for the child whose process ID is equal to
    //         the value of pid.
    //The value of options is an OR of zero or more of the following
    //constants:
    //  WNOHANG
    //    return immediately if no child has exited.
    //  WUNTRACED
    //    also return if a child has stopped (but not traced via
    //    ptrace(2)).  Status for traced children which have stopped
    //    is provided even if this option is not specified.
    //  WCONTINUED (since Linux 2.6.10)
    //    also return if a stopped child has been resumed by
    //    delivery of SIGCONT.
    //Return
    //on success, returns the process ID of the child whose
    //state has changed; if WNOHANG was specified and one or more
    //child(ren) specified by pid exist, but have not yet changed
    //state, then 0 is returned.  On failure, -1 is returned.
    
    pid_t waitpid(pid_t pid, int *status, int options);
    

    测试代码1

    以下代码设计为启动两个进程,然后在主进程等待执行完成,查看返回值后执行主进程

    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main()
    {
      pid_t child1, child2;
      pid_t rc1, rc2;
      printf("parent(pid = %d, ppid = %d\n", getpid(), getppid());
      if ((child1 = fork()) == 0)
      {
        for (int i = 1; i <= 10; i++)
        {
          printf("child1(process=%d%) is working!(pid=%d,ppid=%d)\n", i * 10, getpid(), getppid());
          sleep(1);
        }
        printf("child1 had completed!\n");
      }
      else if (child1 > 0)
      {
        if ((child2 = fork()) == 0)
        {
          for (int i = 1; i <= 10; i++)
          {
            printf("child2(process=%d%) is working!(pid=%d,ppid=%d)\n", i * 10, getpid(), getppid());
            sleep(1);
          }
          printf("child2 had completed!\n");
        }
        else if (child2 > 0)
        {
          //option = 0意味着阻塞父进程等子进程结束
          rc1 = waitpid(child1, NULL, 0);
          rc2 = waitpid(child2, NULL, 0);
          printf("rc1=%d, rc2=%d\n", rc1, rc2);
          printf("child1=%d, child2=%d\n", child1, child2);
    
          for (int i = 1; i <= 3; i++)
          {
            printf("parent(process=%d%) is working!(pid=%d,ppid=%d)\n", i * 10, getpid(), getppid());
            sleep(1);
          }
          printf("parent had completed!\n");
        }
        else if (child2 == -1)
        {
          printf("Error!\n");
        }
      }
      else
      {
        printf("Error!\n");
      }
      return 0;
    }
    

    测试结果1

    • Linux


      Linux测试
    • OHOS(开源鸿蒙开发板,RK3568)


      OHOS测试

    总结1

    Linux下可按照设计目标执行,但是OHOS下waitpid返回值为-1,意味没有找到子进程;但是实际上waitpid是找到子进程并等待子进程执行完毕后才执行的主进程。

    测试代码2

    以下代码设计为启动两个进程,然后在主进程等待执行完成,查看返回值后执行主进程

    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main()
    {
      pid_t child1, child2;
      pid_t rc1, rc2;
      printf("parent(pid = %d, ppid = %d\n", getpid(), getppid());
      if ((child1 = fork()) == 0)
      {
        for (int i = 1; i <= 10; i++)
        {
          printf("child1(process=%d%) is working!(pid=%d,ppid=%d)\n", i * 10, getpid(), getppid());
          sleep(1);
        }
        printf("child1 had completed!\n");
      }
      else if (child1 > 0)
      {
        if ((child2 = fork()) == 0)
        {
          for (int i = 1; i <= 10; i++)
          {
            printf("child2(process=%d%) is working!(pid=%d,ppid=%d)\n", i * 10, getpid(), getppid());
            sleep(1);
          }
          printf("child2 had completed!\n");
        }
        else if (child2 > 0)
        {
          //option = WNOHANG 意味着不阻塞父进程,子进程和父进程交替运行
          rc1 = waitpid(child1, NULL, WNOHANG);
          rc2 = waitpid(child2, NULL, WNOHANG);
          printf("rc1=%d, rc2=%d\n", rc1, rc2);
          printf("child1=%d, child2=%d\n", child1, child2);
    
          for (int i = 1; i <= 3; i++)
          {
            printf("parent(process=%d%) is working!(pid=%d,ppid=%d)\n", i * 10, getpid(), getppid());
            sleep(1);
          }
          printf("parent had completed!\n");
        }
        else if (child2 == -1)
        {
          printf("Error!\n");
        }
      }
      else
      {
        printf("Error!\n");
      }
      return 0;
    }
    

    测试结果2

    • Linux


      Linux测试
    • OHOS


      OHOS测试

总结2

WNOHANG:意味不阻塞进程立即返回,如果子进程存在但是没有状态变化则返回0;Linux执行可看出进程是交替执行的,但是OHOS子进程好像没有抢到执行权限,所以只有等父进程执行完毕后才依次执行子进程。

你可能感兴趣的:(开源鸿蒙测试fork/waitpid)