【Linux】进程等待&进程程序替换

进程等待

僵尸进程的产生原因是:子进程先于父进程退出,在子进程退出时会给父进程发送SIGCHILD信号,而父进程接收到这个信号后选择不处理,从而导致子进程的退出状态信息没有被接收,从而导致子进程成为僵尸进程。

那么正是由于这个原因,我们就需要进行进程等待,来回收子进程的退出状态信息,防止子进程成为僵尸进程。
wait函数就可以实现这个功能

pid_t wait(int* status);

这个函数是一个出参类型的函数,需要我们传入status地址,让wait帮我们将其内部的值进行设置,从而保存退出状态信息
在这里插入图片描述

实际上,status只用了后两个字节,也就是低位的两个字节来保存退出状态信息。
这个函数是一个阻塞类型的函数,也就是说,当wait函数没有接收到子进程退出的退出状态信息,那么程序会一直停到这行代码,直到等到接收到了退出状态信息,才会继续向下执行。

使用status得到退出状态信息的方法,按位与。
在这里插入图片描述
当子进程正常退出,如果传递了status的地址,会得到子进程的退出码
当子进程非正常退出,如果传递了status的地址,会得到子进程的core dump标志位和退出信号。

注意:coredump标志位表示的是子进程如果异常退出了,coredump值为1,表示产生了核心转储文件,0表示没有产生,是否产生核心转储文件不是单纯取决于进程异常退出,而是取决于。

例如当前的代码,子进程会异常退出,但是没有产生coredump文件。
在这里插入图片描述
在这里插入图片描述
可以看到coredump值为0,没有产生核心转储文件,使用ulimit -c查看当前coredump的大小,可以看到大小为0,意味着即使产生了,其大小也为0,所以coredump标志位的值为0。
在这里插入图片描述
通过ulimit -c unlimited将大小设为无限
在这里插入图片描述
这样就可以产生核心转储文件了。

除了使用wait函数之外,也可以使用waitpid来进行进程等待

pid_t waitpid(pid_t pid, int* status, int options);
pidstatusoptions
-1:等待任一子进程子进程的退出状态信息WNOHANG:设置为非阻塞,子进程未结束返回0,结束范围进程pid
0:等待指定pid的进程

需要注意的是:对于非阻塞类型的函数,需要搭配循环来使用

进程程序替换

对于一个bash进程,我们可以通过命令来运行自己的代码,bash进程是当前运行进程的父进程,通过进程概念的理解,我们自己的进程是拷贝了bash的代码的,那么为什么我们的进程不会运行bash进程呢?

原因就是进行了进程程序替换。

通过exec函数簇进行进程程序替换。

其中包含

//path需要带路径,arg第一个参数为可执行程序本身,多个参数用”,“隔开,结尾用NULL,

//若调用成功,则运行替换后的程序,调用失败返回-1
int execl(const char* path, const char* arg,...);

//与上述相同,path不用带路径
int execlp(const char* file, const char* arg,...);

//与上述相同,但是需要自己组织环境变量
int execle(const char* path, const char* arg,..., char* const envp[]);

//与execl相似,但是传递的命令行参数是以数组指针的方式
int execv(const char* path, char* const argv[]);

//与execlp相似,但是传递的命令行参数是以指针数组的方式
int execvp(const char* fail, char* const argv[]);

//与execlp相似,但是传递的命令行参数是以指针数组的方式
int execve(const char* path, char* const argv[], char* const envp[]);

总结起来就是:观察函数尾部带的符号来判断需要传递的参数是什么方式

函数名中带l的函数名中带v的函数名中带p的函数名中带e的
表示传递的参数为可变参数列表表示传递的参数是以数组指针的方式可以使用PATH,无需写全路径需要程序员自己设定环境变量

值得注意的是,除了execve之外,其他的exec函数都是库函数

这里使用execl演示
在这里插入图片描述

运行后的结果

在这里插入图片描述

通过进程等待和进程程序替换来理解守护进程

当某个进程运行的时候,我们需要进程进行守护

创建一个守护进程,让守护进程和被守护的进程进行进程间通信(可以选择共享内存或者消息队列),让被守护的进程每秒发送一个时间,让守护进行读,当守护进程发现前一秒的时间和当前时间相等时,意味着被守护的进程出现了问题,那么就kill掉这个进程,由守护进程创建出一个子进程,使用进程程序替换的方式将当前的子进程替换为要守护的进程,从而实现进程的守护。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux进程管理和进程通信是操作系统中非常重要的概念。我可以为您提供一些关于这两个主题的基本信息。 1. 进程管理: 在Linux中,进程是指在执行中的程序实例。进程管理包括创建、调度、终止和监控进程的活动。以下是一些关于进程管理的关键概念: - 进程标识符(PID):每个进程都有一个唯一的PID,用于标识和跟踪进程。 - 进程状态:进程可以处于运行、就绪、阻塞或终止等不同状态。 - 进程调度:操作系统根据特定算法决定哪个进程应该在给定时间内运行。 - 进程创建:通过fork()系统调用创建子进程,或者通过exec()系列系统调用加载新程序镜像并替换当前进程。 - 进程终止:进程可以自愿终止,或者由其他进程(如父进程或操作系统)强制终止。 - 进程监控:可以使用系统工具(如ps、top)或编程接口(如proc文件系统)来监控和管理进程。 2. 进程通信: 进程通信是指进程之间交换数据和信息的机制。在Linux中,有多种方法可以进行进程间通信,包括: - 管道(Pipe):用于在父子进程或具有亲缘关系的进程之间进行通信。 - 信号(Signal):用于向进程发送简单的通知或中断信号。 - 共享内存(Shared Memory):允许多个进程共享同一块物理内存,以便快速高效地进行数据交换。 - 消息队列(Message Queue):进程可以通过消息队列传递和接收消息。 - 信号量(Semaphore):用于实现进程间的互斥和同步操作。 - 套接字(Socket):适用于网络编程,允许不同主机上的进程进行通信。 这只是对Linux进程管理和进程通信的简要介绍,如果您有任何具体问题或深入了解的需求,请随时提问!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值