Linux启动新进程的三种方法

2019-09-23 09:09:40于丽

父进程执行时,返回子进程的PID

子进程执行时,返回0

代码示例如下:

process_fork.c

#include<stdio.h>
#include<sys/types.h>
int main()
{
  pid_t pid = fork();
  switch(pid)
  {
    case -1:
      perror("fork failed");
      exit(1);
      break;
    case 0:
      printf("n");
      execlp("ps","ps","au",0);
      break;
    default:
      printf("parent,ps donen");
      break;
  }
  exit(0);
}

输出结果:

调用fork函数后,新建了一个子进程,拷贝父进程的代码,数据等到子进程的内存空间。父进程和子进程执行互不影响。使用fork函数的返回值,来区分执行的是父进程,还是子进程。

2)僵尸进程

子进程退出后,内核会将子进程置为僵尸状态。此时,子进程只保留了最小的一些内核数据结构,如退出码,以便父进程查询子进程的退出状态。这时,子进程就是一个僵尸进程。

在父进程中调用wait或waitpid函数,查询子进程的退出状态,可以避免僵尸进程。

原型:

pid_t wait(int *stat_loc);
pid_t waitpid(pid_t pid,int *stat_loc,int options);

stat_loc:若不是空指针,则子进程的状态码会被写入该指针指向的位置。

pid:等待的子进程的进程号pid

options:标记阻塞或非阻塞模式

返回值:成功返回子进程的pid,若子进程没有结束或意外终止,返回0

wait:阻塞模式(使用了信号量),父进程调用wait时,会暂停执行,等待子进程的结束。

wait调用返回后,子进程会彻底销毁。

waitpid:与wait不同的是,

a.可以表示四种不同的子进程类型

     pid==-1 等待任何一个子进程,此时waitpid的作用与wait相同

  pid >0 等待进程ID与pid值相同的子进程

  pid==0 等待与调用者进程组ID相同的任意子进程

  pid<-1 等待进程组ID与pid绝对值相等的任意子进程

b.当options的值为WNOHANG时,为非阻塞模式,即waitpid会立即返回

此时,可以循环查询子进程的状态,若子进程未结束,waitpid返回,做其他工作。

这样提高了程序的效率。

wait函数使用示例如下:

process_fork3.c

#include<wait.h>
#include<stdio.h>
#include<sys/types.h>
int main()
{
  pid_t pid = fork();
  int stat = 0;
  switch(pid)
  {
    case -1:
      perror("fork failed");
      exit(1);
      break;
    case 0:
      printf("n");
      exit(0);
      break;
    default:
      pid = wait(&stat);
      printf("Child has finished:PID=%dn",pid);
      printf("parent,ps donen");
      break;
  }
  exit(0);
}

输出结果: