在如今的时代,多进程编程已经变成了必不可少的一部分,而进程等待、进程替换这两个概念都是作为多进程编程所必不可少的知识,为了掌握多进程编程,今天就从进程等待与替换开始吧。
我们知道linux中进程拥有多种状态,例如僵尸状态、阻塞状态、运行状态等,而其中僵尸状态就是因为父进程没有接受到子进程的退出码而导致的状态,僵尸状态意味着系统无法对进程pcb的资源进行回收,过多的僵尸程序将导致系统内存泄漏、反应卡顿,严重时甚至会让系统挂死。所以,一个正常的多进程程序,父进程必须要接收完所有子进程的退出码,而这个接收的过程就是进程等待 进程等待的方式分为两种: 在C语言中,等待进程的函数为 wait 和 waitpid,它们的差别在与参数的不同。 进程替代是指程序在运行期间执行另一个程序,但这个替换是把整个程序从头到尾都换成了新的程序(pcb还是同样的,所以进程id不变),即使替换的程序结束完毕,也不会回到原有的代码继续执行,所以一般都是由子进程来进行进程替换。 C语言的进程替换函数 虽然函数很多,但其实它们都有着一套很好记得命名规范: 替换实例 博客主页:主页 进程等待的方法
#include
阻塞等待意味着父进程在等待期间是什么都不做的,所以期间只有子进程在运行。#include
非阻塞等待只需把 waitpid 最后的参数改为WNOHANG即可int main()
{
pid_t id = fork(); //在linux系统中使用fork来生成子进程
if(id < 0)
_exit(1); //子进程生成异常
if(id == 0) //分流
{ //子进程
printf("child is run, pid is:%d\n",getpid());
sleep(3);
exit(0);
}
else
{ //父进程
int status = 0;
pid_t ret;
do
{
ret = waitpid(-1, &status, WNOHANG); //非阻塞等待
if (ret == 0)
{
printf("child is running\n");
}
sleep(1);
}while (ret == 0);
if(WIFEXITED(status) && ret == id)
printf("wait child 5s success, child return code is :%d.\n",WEXITSTATUS(status));
else
{
printf("wait child failed, return.\n");
return 1;
}
}
return 0;
}
进程替换
进程替换的概念
替换方式
/*函数如果执行成功将会替换成新的程序,如果执行失败则返回-1*/
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ...,char *const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);
int main()
{
pid_t id = fork();
if(id == 0)
{ //子进程
execlp("exa", "exa", "--icons", NULL); //p代表自动搜索环境变量,无需使用绝对路径
printf("child is exit\n"); //如果execlp执行成功不会打印
exit(1);
}
else
{ //父进程
printf("i'am father, pid:%d\n", getpid());
}
return 0;
}
总结
我的专栏:C++
我的github:github