【Linux学习】进程基础API

下面是有关进程基础API的相关介绍,希望对你有所帮助!

小海编程心语录-CSDN博客

 

目录

1. 僵尸进程与孤儿进程

1.1 孤儿进程

1.2 僵尸进程 

2. 监视子进程

2.1 wait()

2.2 waitpid()

3. 执行新程序 

exec族函数

4. 守护进程


1. 僵尸进程与孤儿进程

1.1 孤儿进程

父进程先于子进程结束,此时子进程变成了一个“孤儿”我们把这种进程就称为孤儿进程。

在 Linux 系统当中,所有的孤儿进程都自动成为 init 进程的子进程

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{// 创建子进程 switch (fork()){case -1:perror("fork error");exit(-1);case 0:// 子进程 printf("子进程<%d>被创建, 父进程<%d>\n", getpid(), getppid());sleep(3);                          // 休眠 3 秒钟等父进程结束printf("父进程<%d>\n", getppid()); // 再次获取父进程 pid_exit(0);default:// 父进程 break;}sleep(1); // 父进程休眠休眠 1 秒,保证子进程能够打印出第一个 printf()printf("父进程结束!\n");exit(0);
}

代码运行结果 

1.2 僵尸进程 

如果子进程先于父进程退出,同时父进程太忙了,无瑕回收子进程的内存资源,那么此时子进程就变成了一个 僵尸进程,僵尸一词指的是子进程结束后其父进程并没有来得及立马给它“收尸”,子进程处于“曝尸荒野”的状态

回收进程有以下几种情况:

  1. 如果父进程调用wait()为子进程收尸"后,僵尸进程就会被内核彻底删除。
  2. 如果父进程并没有调用wait()函数然后就退出了,那么此时init进程将会接管它的子进程并自动调用wait(),故而从系统中移除僵尸进程
  3. 如果父进程创建了某一子进程,子进程已经结束,而父进程还在正常运行,但父进程并未调用wait()回收子进程,此时子进程变成一个僵尸进程

如果系统中存在大量的僵尸进程,它们势必会填满内核进程表,从而阻碍新进程的创建,所以,在我们的一个程序设计中,一定要监视子进程的状态变化,如果子进程终止了,要调用wait()将其回收,避免僵尸进程。

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{// 创建子进程 switch (fork()){case -1:perror("fork error");exit(-1);case 0:// 子进程 printf("子进程<%d>父进程<%d>\n", getpid(), getppid());sleep(1);                          // 休眠 1秒钟printf("子进程结束!\n");_exit(0);default:// 父进程 break;}while(1)sleep(1);exit(0);
}

代码运行结果

2. 监视子进程

在很多应用程序的设计中,父进程需要知道子进程于何时被终止,并且需要知道子进程的终止状态信息,是正常终止、还是异常终止亦或者被信号终止等,意味着父进程会对子进程进行监视,同时还需要回收僵尸进程的资源

2.1 wait()

系统调用 wait() 可以等待进程的任一子进程终止,同时获取子进程的终止状态信息

//函数原型
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);

函数参数和返回值含义如下:

status:参数 status 用于存放子进程终止时的状态信息,参数 status 可以为 NULL,表示不接收子进程 终止时的状态信息。

返回值:若成功则返回终止的子进程对应的进程号;失败则返回-1。

参数 status 不为 NULL 的情况下,则 wait() 会将子进程的终止时的状态信息存储在它指向的 int 变量中,可以通过以下宏来检查 status 参数:

示例代码

#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>int main()
{int status;pid_t pid;int i;int ret;for(i = 1; i<4; i++){pid = fork();switch(pid){case -1:perror("fork error");exit(-1);case 0:// 子进程 printf("子进程<%d>被创建\n", getpid());sleep(i);                         _exit(i);default:// 父进程 break;}}sleep(1);for(i = 1; i<4; i++){ret = wait(&status);if(ret == -1){if(ECHILD == errno){printf("没有等待回收的进程\n");exit(0);}else{perror("wait error");exit(-1);}}printf("回收的子进程id: %d,回收状态:%d\n", ret, WIFSIGNALED(status));}exit(0);
}

 代码运行结果

2.2 waitpid()

使用 wait()系统调用存在着一些限制,这些限制包括如下:

如果父进程创建了多个子进程,使用 wait()将无法等待某个特定的子进程的完成,只能按照顺序等待下一个子进程的终止,一个一个来、谁先终止就先处理谁。

如果子进程没有终止,正在运行,那么 wait() 总是保持阻塞,有时我们希望执行非阻塞等待,而waitpid()函数则可以突破这些限制。

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

status: 与 wait()函数的 status 参数意义相同

返回值: 返回值与 wait()函数的返回值意义基本相同

3. 执行新程序 

当子进程的工作不再是运行父进程的代码段,而是运行另一个新程序的代码,那么这个时候子进程可以通过 exec 函数来实现运行另一个新的程序。

exec族函数

exec 族函数包括多个不同的函数,这些函数命名都以 exec 为前缀,这些库函数都是基于系统调用 execve() 而实现的,虽然参数各异、但功能相同, 包括: execl()、 execlp()、 execle()、 execv()、 execvp()、 execvpe()

示例代码 

// child.c
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/wait.h> int main(int argc, char **argv)
{// 倒数 n 秒for(int i=atoi(argv[1]); i>0; i--){printf("%d\n", i);sleep(1);}// 程序退出,返回 nexit(atoi(argv[1]));
}
// father.c
#include <stdio.h> 
#include <unistd.h> 
#include <sys/wait.h> int main()
{// 子进程if(fork() == 0){printf("加载新程序之前的代码\n");// 加载新程序,并传递参数3execl("./child", "./child", "3", NULL);printf("加载新程序之后的代码\n");}// 父进程else{// 等待子进程的退出int status;int ret = waitpid(-1, &status, 0);if(ret > 0){if(WIFEXITED(status))printf("[%d]: 子进程[%d]的退出值是:%d\n",getpid(), ret, WEXITSTATUS(status));}else{printf("暂无僵尸子进程\n");}}
}

代码运行结果

  • 注意:子进程中加载新程序之后的代码无法运行,因为已经被覆盖了。

4. 守护进程

守护进程(Daemon) 也称为精灵进程,是运行在后台的一种特殊进程,它独立于控制终端并且周期性 地执行某种任务。

输入终端命令 ps -aux TTY 一栏是  ?表示该进程没有控制终端,也就是守护进程,其中 COMMAND 一栏使用中括号[]括 起来的表示内核线程,这些线程是在内核里创建,没有用户空间代码,因此没有程序文件名和命令行,通常 采用 k 开头的名字,表示 Kernel


如果喜欢请不吝给予三连支持!

小海编程心语录-CSDN博客

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/13801.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(5)SK插件

&#xff08;5&#xff09;SK插件 什么是AI插件&#xff1f; 使用人工智能插件的目的是通过利用人工智能能力来增强软件应用程序的功能。人工智能插件可以提供各种功能&#xff0c;如自然语言处理、图像识别、预测分析等。 通过将AI插件集成到应用程序中&#xff0c;您可用为…

通过 Spring 操作 Redis

要想通过 Java 操作 redis&#xff0c;首先要连接上 redis 服务器&#xff0c;推荐看通过 Java 操作 redis -- 连接 redis 创建项⽬ 勾选 NoSQL 中的 Spring Data Redis 当然, 把 Web 中的 Spring Web 也勾选⼀下.⽅便写接进⾏后续测试. 配置 redis 服务地址 在 application.…

基于springboot + vue实现工厂车间管理系统项目演示【附项目源码+论文说明】

基于springboot vue实现工厂车间管理系统演示 摘要 社会发展日新月异&#xff0c;用计算机应用实现数据管理功能已经算是很完善的了&#xff0c;但是随着移动互联网的到来&#xff0c;处理信息不再受制于地理位置的限制&#xff0c;处理信息及时高效&#xff0c;备受人们的喜…

PasteSpider更新摘要(持续更新... .. .)

写在前面 PasteSpider整个项目分为三大块PasteSpider(主端我称为API(.net 6.0)),PasteSpiderWeb(后台管理端(js,html,css)),PasteSpiderFile(文件同步端(.net6.0)&#xff0c;一键部署&#xff0c;差量同步等就是用他&#xff0c;不然每次升级要打开网站后台很麻烦的&#xff…

springboot+jsp校园理发店美容美发店信息管理系统0h29g

前台管理:会员管理、会员预定、开单点单、收银结帐、技师提成 后台管理:数据维护、物料管理、数据查询、报表分析、系统设置等 灵活的付款方式&#xff0c;支持现金、挂帐、会员卡&#xff0c;同时支持多种折扣方式并可按用户要求设置多种结帐类型善的充值卡管理模块:支持优惠卡…

大创项目推荐 深度学习手势识别 - yolo python opencv cnn 机器视觉

文章目录 0 前言1 课题背景2 卷积神经网络2.1卷积层2.2 池化层2.3 激活函数2.4 全连接层2.5 使用tensorflow中keras模块实现卷积神经网络 3 YOLOV53.1 网络架构图3.2 输入端3.3 基准网络3.4 Neck网络3.5 Head输出层 4 数据集准备4.1 数据标注简介4.2 数据保存 5 模型训练5.1 修…

某东-绑卡

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;wx a15018601872 本文章未…

【文末附gpt升级方案】AIGC(人工智能):技术革命与人类未来的深度解析

AIGC&#xff08;人工智能&#xff09;&#xff1a;技术革命与人类未来的深度解析 摘要&#xff1a;随着科技的不断进步&#xff0c;人工智能&#xff08;AI&#xff09;已成为现代社会的重要支柱。其中&#xff0c;AIGC&#xff08;Artificial Intelligence Generated Conten…

Qt5 互动地图,实现无人机地面站效果

一、概述 本文主要通过Qt5opmapcontrol实现一个简单的无人机地面站效果。opmapcontrol是一个比较古老的QT开源地面站库&#xff0c;可选择谷歌地图&#xff0c;必应地图&#xff0c; 雅虎地图&#xff0c;GIS等。可直接使用源码&#xff0c;也可以编译生成库进行调用。实现效果…

Mujoco仿真【xml文件的学习 2】

承接上一篇的博客&#xff1a;Mujoco仿真【xml文件的学习 1】-CSDN博客 我们继续来学习Mujoco仿真中的xml文件&#xff0c;哦豁&#xff0c;gogogo&#xff01; 给出这次的xml文件案例【bimanual_viperx_transfer_cube.xml】&#xff1a; <mujoco><include file&qu…

EventSource 在项目中常用的两种方式

一、认识EventSource EventSource&#xff08;也称为Server-Sent Events&#xff0c;简称SSE&#xff09;是HTML5中的一种新的API&#xff0c;用于实现服务器端向客户端推送事件。其数据主要基于HTTP协议进行传输&#xff0c;并且数据帧必须编码成UTF-8的格式。 eventSource…

本地电子邮件测试工具-MailHog

通过MailHog&#xff0c;可以在浏览器中查看本机发的邮件内容&#xff0c;而无需发送到外网。 https://github.com/mailhog/MailHog在 macOS 环境下&#xff0c;下载文件后: 添加可执行权限:chmod x MailHog_darwin_amd64 运行:./MailHog_darwin_amd64 浏览器打开查看邮件:htt…

LitCTF

[LitCTF 2023]enbase64 base 64 里面有一个换表的函数 写代码 #include<stdio.h> #include<string.h> #include<stdlib.h> int main() {char *result; char Destination[65]; int v3[65];int j;int i; char Source[]"ABCDEFGHIJKLMNOPQRSTUVWXYZabcde…

【Python设计模式15】适配器模式

适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而无法一起工作的类能够一起工作。通过使用适配器模式&#xff0c;可以使得现有的类能够适应新的接口需…

打造高效安全新标杆:智慧楼宇视频智能管理系统的建设探索

大数据、人工智能、5G等技术在城市中的不同应用也让人们看到了数字化和智能化技术赋予城市管理的巨大潜力&#xff0c;为更多城市数字化应用场景的发展带来机遇。在新基建的大背景下&#xff0c;人工智能、物联网等先进技术与基础设施的深度融合&#xff0c;将大力推进电网、楼…

PostgreSQL自带的命令行工具25- ecpg

PostgreSQL自带的命令行工具25- ecpg ecpg 是 PostgreSQL 提供的一个工具&#xff0c;允许在 C 语言程序中嵌入 SQL 语句&#xff0c;从而能够与 PostgreSQL 数据库进行交互。ecpg 全称是 Embedded SQL in C&#xff0c;采用了标准的 SQL 预编译技术&#xff0c;将 SQL 语句嵌…

ArcGIS批量更改所有符号的格式

这期谈一下&#xff0c;如何修改所有符号的样式。 比如&#xff0c;我们需要更改下图的面符号位无轮廓的 该如何批量修改的呢&#xff1f; 视频教学吧&#xff1a; ArcGIS批量更改所有符号的格式 ArcGIS全系列实战视频教程——9个单一课程组合系列直播回放-CSDN博客文章浏览阅…

el-input 自动获取焦点

前言&#xff1a; 需求描述&#xff1a;在 Dialog 对话框中 使用 input 组件&#xff1b;当点击按钮&#xff0c;Dialog 对话框显示&#xff0c;且里面的 input 组件要自动获取焦点。因为页面上还存在其他的 input 组件&#xff0c;所以使用 自动获取焦点属性没用&#xff01;&…

Docker仓库解析

目录 1、Docker仓库类型2、Docker仓库的作用3、工作原理4、管理与使用最佳实践 Docker仓库是Docker生态系统中的重要组成部分&#xff0c;它是用于存储和分发Docker镜像的集中化服务。无论是公共还是私有&#xff0c;仓库都是开发者之间共享和复用容器镜像的基础。 1、Docker仓…

2024年5月23号PMP每日三题含答案

2024年5月23号PMP每日三题含答案 1.项目可交付成果已移交给客户&#xff0c;项目经理现在必须收集项目参与者的反馈意见。项目经理应该查阅哪份文件来确定哪些人应该被包含进请求反馈意见的名单中&#xff1f; A.干系人登记册 B.沟通管理计划 C.经验教训 D.项目资源管理计划 1…