【Linux】---进程控制(创建、终止、等待、替换)

进程创建

fork()

fork函数在之前的文章中也已经提到过了。其主要作用是从已存在的进程中创建一个新的进程,也就是新建的进程为子进程,原进程为父进程

当一个进程调用fork函数后,内核会做几件事:

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

下面来看看进程创建的一段简单代码

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

int main(){
   
    pid_t id = fork();
    
    if(id == 0){
   
        printf("I am child process, pid = %d, ppid = %d\n", getpid(), getppid());
    }
    
    printf("I am parent process, pid = %d, ppid = %d\n", getpid(), getppid());
    return 0;
}

image-20221128143753830

当其返回值为0时,说明创建出了子进程。

进程退出

进程退出场景

进程退出总共会有三种情况,也就是我们平常写代码执行的时候也是会遇到这三种情况:

  1. 代码运行完毕,结果正确
  2. 代码运行完毕,结果不正确
  3. 代码遇到异常终止执行

进程退出方法

对于进程退出而言,可以有两种方法退出。一种就是正常的程序运行完毕终止执行,另一种就是程序遇到异常信号终止运行。

那么现在有一个问题,我们平常写代码的时候为什么总是会带上一个 return 0 呢?这里就涉及到一个知识点—退出码

退出码

其实return 0这个0并没有什么特殊的意思,返回的是0就代表着程序执行正常退出,非0就是程序有错误,每一个非0的退出码都代表着不同的错误信息。可以通过程序看看

#include<stdio.h>
#include<string.h>

int main(){
   
	for(int i = 0; i < 20; i++)
		printf("%d: %s\n", i, strerror(i));
	
	return 0;
}

image-20221128145109320

exit、_exit

那么除了return可以返回退出码退出程序外,exit和**_exit**也是可以的。不过这两者之间还是会有所区别的。

  1. exit是库函数,_exit是系统调用
  2. exit会刷新缓冲区,_exit不会

进程等待

进程等待是非常重要的。之前在进程状态里面谈到了一种状态—僵尸状态。这种状态是非常危险的,会造成内存泄漏。并且一旦进程变成了僵尸状态,那么即使使用kill -9都无法将其杀死。

所以父进程想要获取子进程的任务完成的程度如何,就必须通过进程等待的方式,回收子进程资源,获取子进程退出信息

进程等待的方法

进程等待有两种方法:1、阻塞等待;2、非阻塞等待。可以使用两个函数去实现:wait和waitpid

image-20221128150111166

wait

wait等待成功会返回被等待的进程的pid,失败则返回-1,下面来一段代码感受一下

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/wait.h>

int main(){
   
  pid_t id = fork();

  if(id == 0){
   
    int cnt = 5;
    while(cnt--){
   
      printf("I am child process, pid = %d\n", getpid());
      sleep(1);
    }
    exit(1);
  }

  pid_t ret = wait(NULL);
  printf("%d\n", ret);

  return 0;
}

image-20221128151017389

可以看到进程最后打印出的是子进程的pid,说明等待成功了。

waitpid

waitpid 相对于 wait 来说能够获取的信息就更多了,可以获取子进程的退出码和子进程返回的状态。

如果子进程是正常终止,那么返回的状态为0,如果收到了异常信号终止则非0

但是这里还要注意的是,waitpid 返回的子进程的数据是有自己的存储方式的。例如 waitpid 返回了一个变量 status 那么这个变量的**高八位为退出状态,低八位为终止信号。

image-20221128151748607

如果进程是被信号所杀,则退出状态就没有用到,终止信号根据实际。如果进程正常终止,则退出状态根据实际,终止信号为0.

所以当waitpid 返回了一个值,我们想要获取终止信号就得用这个值 & 0x7f;获取退出状态就得用这个变量 向右移动8位再 & 0xff

来一段代码感受一下

#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值