Linux-进程控制(进程创建、进程终止、进程等待)

一、进程创建

1.1 fork函数介绍

        在命令行下我们可以通过 ./ + exe文件 来创建一个进程,通过fork函数,我们可以通过代码的形式从一个进程中创建一个进程,新进程为子进程,原进程为父进程,子进程在创建时,会与父进程共享下面的代码与数据,当数据被修改时,会采用写实拷贝的方式保证进程间的独立性。

//头文件
#include<unistd.h>

//函数
pid_t fork()

//返回值
 #子进程中返回0
 #父进程返回子进程id
 #出错返回-1

进程调用fork,当控制转移到内核中的fork代码后,内核做:

  • 分配新的内存块和内核数据结构给子进程
  • 将父进程部分数据结构内容拷贝至子进程
  • 添加子进程到系统进程列表当中
  • fork返回,开始调度器调度

fork函数常规用法:

  • 一个父进程希望复制自己,使父子进程同时执行不同的代码段。例如,父进程等待客户端请  求,生成子进程来处理请求。
  • 一个进程要执行一个不同的程序。例如子进程从fork返回后,调用exec函数

fork函数失败原因:

  • 系统中有太多的进程
  • 实际用户的进程数超过了限制
     
1.2 使用举例
  #include<unistd.h>
  #include<stdio.h>
  #include<stdlib.h>
  int main()
  {
    //父进程
    printf("I am parent process ppid:%d pid:%d\n",getppid(),getpid());
    //创建子进程
    pid_t id=fork();
    //根据id的值分流,使父子进程执行不同的代码
    if(id == -1)
    {
      exit(-1);
    }
    else if(id == 0)
    {
      //子进程
       printf("I am child process ppid:%d pid:%d\n",getppid(),getpid());
    }
    else
    {                                                                                                                                                                                          
      //父进程
       printf("I am parent process ppid:%d pid:%d\n",getppid(),getpid());
    }
    return 0;
  }

二、进程终止

2.1 进程退出场景

  • 代码运行完毕,结果正确
  • 代码运行完毕,结果不正确
  • 代码没有运行完,发现异常,提前终止

 2.2 错误码与信号码

错误码
  • 在main函数中,我们通常会return 0,return -1等等,那这些数字有什么意义吗?
  //strerror可以查看错误码信息
  #include<unistd.h>
  #include<stdio.h>
  #include<stdlib.h>
  #include<string.h>                                                                                                                                                                           
  int main()
  {
    int i=0;
    for(i=0;i<255;i++)
    {
      printf("%d:%s\n",i,strerror(i));
    }
    return 0;
  }

可以看到,不同的数字拥有不同的含义,0表示成功,非0表示错误,当程序执行完后,操作系统会检测到错误,并将错误信息打印出来,反馈给用户,这样就可以通过查看错误码来确定程序终止的情况,例如:

ps:操作系统中存在一个变量,名字就叫 ,它保存了最近一次进程的错误码,可以通过

echo $? 查看

信号码
  • 模拟野指针异常:
  
   int main()  
  {  
    int* p=NULL;
    *p=1;
    retrun 0;                                                                                                                                                                                  
  }  

  • 通过kill -11 给进程发信号

通过上述两个例子可以看出,异常终止也是因为OS给进程发了信号,让进程终止的

可以通过kill -l 查看所有信号

总结:

确认进程终止情况的方法:

1.先判断是否是异常导致

2.是异常通过查看信号码确定异常信息

3.不是异常直接看错误码确定错误信息即可

三、进程等待

3.1 进程等待的必要性
  • 子进程退出后,若父进程不进行管理,就会造成僵尸进程,会导致内存泄露问题
  • 父进程派给子进程的任务完成的如何,我们需要知道。如,子进程运行完成,结果对还是不对,或者是否正常退出
  • 父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息
3.2 进程等待方法
3.2.1 wait
#include<sys/types.h>
#include<sys/wait.h>

pid_t wait(int*status);

#返回值:
成功返回被等待进程pid,失败返回-1。

#参数:
输出型参数,获取子进程退出状态,不关心则可以设置成为NULL
  #include <stdio.h>
  #include <unistd.h>
  #include <string.h>
  #include <stdlib.h>
  #include <sys/types.h>
  #include <sys/wait.h>
  
  void ChildRun()
  {
      int cnt = 5;
      while(cnt)
      {
          printf("I am child process, pid: %d, ppid:%d, cnt: %d\n", getpid(), getppid(), cnt    );
          sleep(1);
          cnt--;
      }
  }
  
  int main()
  {
      printf("I am father, pid: %d, ppid:%d\n", getpid(), getppid());
  
      pid_t id = fork();
      if(id == 0)
      {
          // child
          ChildRun();                                                                       
          printf("child quit ...\n");
          exit(0);
      }
      // fahter
     pid_t rid = wait(NULL);
     if(rid>0)
     {
       printf("wait success pid:%d\n",rid);
     }
     return 0;
  }
3.2.2 waitpid
//头文件: 
#include<sys/type.h>
#include<sys/wait.h>

pid_t waitpid(pid_t pid,int *status,int options)

#返回值:

  • 当正常返回的时候waitpid返回收集到的子进程的进程ID;
  • 如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;
  • 如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;

#参数:
pid:

  • Pid=-1,等待任一个子进程。与wait等效。
  • Pid>0.等待其进程ID与pid相等的子进程。

status:

  • WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)
  • WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码)

options:
WNOHANG: 若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若正常结束,则返回该子进程的ID。

3.3 获取子进程status

父进程要获取子进程的退出信息最重要的就是错误码与信号码,而进程PCB中会存在两个整形变量,用于保存错误码与信号码信息,操作系统可以根据wait与waitpid中status ,将子进程的信息传递给父进程

status不能简单的当作整形来看待,可以当作位图来看待,具体细节如下图(只研究status低16比特位):


  #include <stdio.h>
  #include <unistd.h>
  #include <string.h>
  #include <stdlib.h>
  #include <sys/types.h>
  #include <sys/wait.h>
  
  void ChildRun()
  {
      int cnt = 5;
      while(cnt)
       {
          printf("I am child process, pid: %d, ppid:%d, cnt: %d\n", getpid(), getppid(), cnt    );
          sleep(1);
          cnt--;
      }
  }
  
  int main()
  {
      printf("I am father, pid: %d, ppid:%d\n", getpid(), getppid());
  
      pid_t id = fork();
      if(id == 0)
      {
          // child
          ChildRun();
          printf("child quit ...\n");
          exit(123);
      }
      sleep(7);
       // fahter
      //pid_t rid = wait(NULL);                                                             
      int status = 0;
      pid_t rid = waitpid(id, &status, 0);
      if(rid > 0)
      {
          printf("wait success, rid: %d\n", rid);
      }
      else
      {
  printf("wait failed !\n");
      }
      sleep(3);
      printf("father quit, status: %d, child quit code : %d, child quit signal: %d\n", statu    s, (status>>8)&0xFF, status & 0x7F);
  }

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-25 15:50:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-25 15:50:04       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-25 15:50:04       82 阅读
  4. Python语言-面向对象

    2024-03-25 15:50:04       91 阅读

热门阅读

  1. IOS面试题编程机制 36-40

    2024-03-25 15:50:04       39 阅读
  2. 「Linux系列」Shell 输入/输出重定向

    2024-03-25 15:50:04       43 阅读
  3. Flask蓝图找不到路由地址,访问404

    2024-03-25 15:50:04       39 阅读
  4. git 代码冲突处理

    2024-03-25 15:50:04       35 阅读
  5. 机器人|逆运动学问题解决方法总结

    2024-03-25 15:50:04       37 阅读
  6. PyTorch张量

    2024-03-25 15:50:04       45 阅读
  7. 用go实现一个任务调度类 (泛型)

    2024-03-25 15:50:04       43 阅读
  8. C++之Const与指针

    2024-03-25 15:50:04       34 阅读
  9. C++之内存分区

    2024-03-25 15:50:04       42 阅读
  10. ChatGPT:开启智能对话,提升论文写作能力

    2024-03-25 15:50:04       35 阅读
  11. 线段树CF 练习题

    2024-03-25 15:50:04       45 阅读
  12. oppo,快手25届暑期实习内推

    2024-03-25 15:50:04       43 阅读