当前位置: 首页 > news >正文

Linux 进程(2)

进程的回收
1.wait

原型

pid_t wait(int *status);

功能:该函数可以阻塞等待任意子进程退出
      并回收该进程的状态。
  一般用于父进程回收子进程状态。

参数:status 进程退出时候的状态
  如果不关心其退出状态一般用NULL表示
  如果要回收进程退出状态,则用WEXITSTATUS回收。

返回值:

        成功时,wait返回终止子进程的PID。

        失败时,返回-1,并设置errno来指示错误。

关于子进程状态的一些宏定义:

1.WIFEXITED(status)  是不是正常结束,如果返回非零值,则表示子进程正常结束了它的main函数,或者调用了exit()函数。
2.WEXITSTATUS(status)  为真时,使用这个宏来获取子进程的退出状态码。状态码是由main函数的返回值或者exit()函数的参数决定的。
3.WIFSIGNALED(status) 检查子进程是否是因为接收到信号而终止的。如果返回非零值,则表示子进程是因为信号而终止。    
4.WTERMSIG(status) 为真时,使用这个宏来获取导致子进程终止的信号编号。

5.WIFSTOPPED(status): 检查子进程是否因为接收到SIGSTOPSIGTSTPSIGTTINSIGTTOU信号而停止。如果返回非零值,则表示子进程已经停止。

6.WSTOPSIG(status): 当WIFSTOPPED(status)为真时,使用这个宏来获取导致子进程停止的信号编号。

7.WIFCONTINUED(status): 检查子进程是否已经从停止(stopped)状态继续执行。如果返回非零值,则表示子进程已经继续。

举例:


int a=20;
int main(int argc, const char *argv[])
{pid_t ret =fork();if(ret>0){//printf("father is %d   pid= %d,ppid= %d \n",a,getpid(),getppid());wait(NULL);printf("after wait\n");sleep(5);}else if(0==ret){printf("child = %d pid:%d ppid:%d",a,getpid(),getppid());sleep(3);printf("child terminal\n");exit(1);}else{perror("fork");return 1;}printf("a:%d  pid:%d",a,getpid());return 0;
}

利用宏定义,判断子进程的状态

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
int a = 20;
int main(int argc, char *argv[])
{pid_t ret = fork();if(ret>0){//fatherprintf("father is %d   pid %d ,ppid:%d  \n",a,getpid(),getppid());int status;pid_t pid = wait(&status);if(WIFEXITED(status))// 代表子进程正常结束{//正常结束的子进程,才能获得退出值printf("child quit values %d\n",WEXITSTATUS(status));}if(WIFSIGNALED(status))//异常结束{printf("child unnormal signal num %d\n", WTERMSIG(status));}printf("after wait, %d\n",status);}else if(0 == ret){//childprintf("child a is %d pid:%d ppid:%d\n",a,getpid(),getppid());sleep(5);printf("child terminal\n");exit(50);}else {perror("fork error\n");return 1;}printf("a is %d pid:%d\n",a,getpid());return 0;
}
2.waitpid

原型

#include <sys/types.h>
#include <sys/wait.h>pid_t waitpid(pid_t pid, int *status, int options);

参数说明:

  • pid: 子进程的PID。如果设置为 -1,则表示等待任一子进程,这与 wait 函数的行为相同。
  • status: 指向整数的指针,用于接收子进程的状态信息。如果不需要状态信息,可以传递 NULL
  • options: 指定等待行为的选项,常用的选项有:
    • WNOHANG: 如果子进程尚未终止,调用立即返回,而不是挂起等待。
    • 0:  表示回收过程会阻塞等待

返回值:

  • 成功时,返回子进程的PID。
  • 如果子进程尚未终止(使用了 WNOHANG 选项),返回 0。
  • 失败时,返回 -1,并设置 errno 以指示错误

练习:

设计一个多进程程序,用waitpid函数指定回收
其中的某个进程资源并将其状态打印输出。
其他的进程都以非阻塞方式进行资源回收。

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{int i = 0 ;pid_t ret[5]={0};printf("father  pid %d ,ppid:%d  \n",getpid(),getppid());for(i = 0 ;i<5;i++){ret[i] = fork();if(ret[i]>0){//father}else if(0 == ret[i]){//childprintf("child  pid:%d ppid:%d\n",getpid(),getppid());sleep(rand()%5);exit(1);}else {perror("fork error\n");return 1;}}int status;while(1){pid_t pid = waitpid(ret[2],&status, WNOHANG);if(ret[2] == pid){if(WIFEXITED(status))// 代表子进程正常结束{//正常结束的子进程,才能获得退出值printf("child quit values %d\n",WEXITSTATUS(status));}if(WIFSIGNALED(status))//异常结束{printf("child unnormal signal num %d\n", WTERMSIG(status));}printf("father recycle success, pid :%d\n",pid);break;}else if(0 == pid){printf("子进程未结束,稍后在试\n");//usleep(1000);sleep(1);}}printf("after wait, %d\n",status);return 0;
}

exec

exec函数族在 C 语言中用于在当前进程的上下文中执行一个新的程序。exec 函数不会创建新的进程,而是替换当前进程的映像为新程序的映像。这意味着进程的PID保持不变,但是执行的程序完全改变。

exec族函数

  1. execl(const char *path, const char *arg0, ...):

            加载并执行由 path 指定的程序,arg0 是传递给新程序的主参数,后面可以跟随其他参数,以 NULL 结尾。
  2. execv(const char *path, char *const argv[]):

              加载并执行由 path 指定的程序,argv 是一个以 NULL 结尾的参数数组。
  3. execle(const char *path, const char *arg0, ..., char *const envp[]):

               与 execl 类似,但允许指定一个新的环境指针数组 envp,替换当前环境。
  4. execve(const char *path, char *const argv[], char *const envp[]):

               加载并执行由 path 指定的程序,argv 是参数数组,envp 是环境变量数组。
  5. execlp(const char *file, const char *arg0, ...):

               与 execl 类似,但在 PATH 环境变量中搜索程序 file
  6. execvp(const char *file, char *const argv[]):

               与 execv 类似,但在 PATH 环境变量中搜索程序 file
  7. execvpe(const char *file, char *const argv[], char *const envp[]):

               与 execve 类似,但在 PATH 环境变量中搜索程序 file,并允许指定新的环境变量数组 envp

举例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{//  firefox www.baidu.com //execl("/usr/bin/firefox","firefox","www.baidu.com",NULL);// env echo $PATH  ls -l --color=auto ll//execlp("ls","ls","-l","--color=auto",NULL);char *const args[]={"ls","-l","--color=auto",NULL};//execv("/bin/ls",args);//vector// pathexecvp(args[0],args);//vector+pathprintf("看见就错了\n");exit(1);return 0;


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{//  firefox www.baidu.com //execl("./aaa","aaa","1","2","3",NULL);// env echo $PATH  ls -l --color=auto ll//execlp("./aaa","aaa","1","2","3",NULL);char *const args[]={"aaa","1","2","3",NULL};//execv("./aaa",args);//vector// pathexecvp("./aaa",args);//vector+patha//如果需要都能调用成功,第一个参数都传 路径+文件名printf("看见就错了\n");exit(1);return 0;
}

http://www.lryc.cn/news/429244.html

相关文章:

  • [CSCCTF 2019 Qual]FlaskLight1
  • layui table表单 checkbox选中一个其它也要选中
  • 【pip镜像设置】pip使用清华镜像源安装
  • c++ 智能指针--std::shared_ptr
  • 网络工程师学习笔记(二)
  • 90.WEB渗透测试-信息收集-Google语法(4)
  • 阿里Qwen2开源大模型本地部署及调试全攻略
  • 『功能项目』移动后的光标显示【04】
  • HTML 基本语法特性与 title 标签介绍
  • CSS的:placeholder-shown伪类:精确控制输入框占位符样式
  • Java之HashMap的底层实现
  • 多张图片进行模型重建并转换为OBJ模型
  • 信息安全保证人员CISAW:安全集成
  • 别再无效清理微信内存啦,这才是正确清理内存的方式
  • ant design 的 tree 如何作为角色中的权限选择之一
  • 如何在项目管理中完成项目立项?
  • LearnOpenGL——延迟渲染学习笔记
  • 惠海H4312 dcdc同步整流降压恒压IC 30V 40V转3.3V/5V/12V小体积大电流单片机供电
  • [Linux]如何在虚拟机安装Ubuntu?(小白向)
  • keepalived详解
  • 工业设备中弧形导轨的检测标准是什么?
  • Redis 技术详解
  • Kubernetes Pod入门
  • opencv批量修改图片大小
  • 【RTT-Studio】详细使用教程十二:UART的分析和使用
  • 【AI绘画】Midjourney前置指令/settings设置详解
  • 【NI国产替代】PXIe‑4330国产替代24位,8通道PXI应变/桥输入模块
  • 哪里可以免费上传招生简章
  • Midjourney中文版教程:参数详解
  • 误闯机器学习(第一关-概念和流程)