【Linux】进程exec函数族以及守护进程

一.exec函数族

1.exec函数族的应用

        在shell下敲shell的命令都是在创建shell的子进程。而我们之前学的创建父进程和子进程代码内容以及通过pid与0的关系来让父子进程执行不同的代码内容都是在一个代码文件里面,而shell是如何做到不在一个文件里面写代码使之成为子进程的呢?

        答案是使用了exec函数族

假如现在有段在shell下敲的名为test的代码,执行过程为:父进程(shell)fork()出一个子进程后,子进程调用exec函数族执行test,此时原进程的内容就会被覆盖,执行test的内容,就实现了创建新的进程并在该进程中执行不同的程序;

这些函数允许将当前进程内容替换为新的可执行文件,从而实现进程的代码和数据的切换。

进程调用exec函数族执行某个程序

进程当前内容被指定的程序替换

实现让父子进程执行不同的程序 :

●父进程创建子进程  

●子进程调用exec函数族  

●父进程不受影响

2.exec函数族的一些常见成员

(1)excel / excelp(熟练)

#include  <unistd.h>
int execl(const char *path, const char *arg, …);
int execlp(const char *file, const char *arg, …);

 成功时执行指定的程序;失败时返回EOF

 path   执行的程序名称,包含路径

 arg…  传递给执行的程序的参数列表

 file   执行的程序的名称,在PATH中查找(PATH为linux的环境变量,添加到系统的环境变量后,在系统的任意路径都能直接输入程序名称执行,不用输入路径)

execl : 以参数列表的方式执行新程序。需要指定可执行文件的路径,以及传递给新程序的参数列表。

进程创建 – execl(p) – 示例:

 ⭕ 执行ls命令,显示/etc目录下所有文件的详细信息

#include <stdio.h>
#include <unistd.h>int main(int argc, const char *argv[])
{if(execl("/bin/ls","ls","-a","-l","/etc",NULL)<0){perror("execl");}return 0;
}
#include <stdio.h>
#include <unistd.h>int main(int argc, const char *argv[])
{if(execlp("ls","ls","-a","-l","/etc",NULL)<0){perror("execl");}return 0;
}

分析:

execl中:

"/bin/ls"为执行的程序名称,在/bin路径下有个叫ls的程序;

"ls"是第0个参数,第0个参数通常是程序的名称,第0个参数必须要写,虽然它没有使用;

"-a","-l","/etc"都是传递给程序的参数;

execlp中:除了直接传入程序名称在系统路径中查找以外,其余和execl相同;

注意:两个函数区别在于execlp不需要写文件名全路径,在系统路径PATH查找

            最后一个参数都必须用空指针(NULL)作结束

            进程当前内容被指定的程序替换,但进程号不变

            第0个参数必须要写,虽然它没有使用

(2)execv / execvp (熟练)

  #include  <unistd.h>int execv(const char *path, char *const argv[]);int execvp(const char *file, char *const argv[]);

成功时执行指定的程序;失败时返回EOF  ;

arg… 封装成指针数组的形式;

这两个就是把参数列表封装成了一个数组;

进程创建 – execv(p) – 示例

⭕执行ls命令,显示/etc目录下所有文件的详细信息

伪代码如下:

  char  *arg[] = {“ls”, “-a”, “-l”, “/etc”, NULL};if  (execv(“/bin/ls”, arg) < 0){perror(“execv”);}  if  (execvp(“ls”, arg) < 0){perror(“execvp”);}  

注意:末尾的NULL照样不能省;

3.system(exec的简略版本) (熟练)

内部使用了 exec 函数族的一种方式来执行 shell 命令

#include  <stdlib.h>
int system(const char *command);

成功时返回命令command的返回值;失败时返回EOF

当前进程system 函数会创建一个子进程来执行 shell 命令,等待执行结束后才继续执行

system 函数一般用来执行shell命令,并不适用于直接执行可执行程序,一般使用exec函数族来执行可执行程序。

#include <stdlib.h>int main(int argc, const char *argv[])
{system("/bin/ls -a -l /etc");return 0;
}

二.守护进程

1.守护进程的特点(了解)

(1)守护进程

守护进程(Daemon Process)是Linux三种进程类型之一;

是 Linux 中的后台服务进程;

是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件;

(2)守护进程特点

始终在后台运行

独立于任何终端

周期性的执行某种任务或等待处理特定事件

它是个特殊的孤儿进程,这种进程脱离终端,为什么要脱离终端呢?之所以脱离于终端是为了避免进程被任何终端所产生的信息所打断,其在执行过程中的信息也不在任何终端上显示。由于在 Linux 中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端就称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会自动关闭

举例:

http 服务的守护进程叫 httpd,mysql 服务的守护进程叫 mysqld。

2.会话、控制终端(了解)

进程组(Process Group): 进程集合,每个进程组有一个组长(Leader),其进程 ID 就是该进程组 ID。

会话(Session): 进程组集合,每个会话有一个组长,其进程 ID 就是该会话组 ID。

控制终端(Controlling Terminal):每个会话可以有一个单独的控制终端,与控制终端连接的 Leader 就是控制进程(Controlling Process)。

即进程的集合为进程组,进程组集合为会话组 ,会话组的控制终端为控制进程;

3.创建守护进程流程(熟练)

简便地创建守护进程: nohup 命令

nohup  xxxx  &

nohup在某些情况下是方便的,但是需要创建更稳定和更高级需求的守护进程时并不推荐nohup;

接下来我们介绍学习另外的方法:

(1)创建子进程,父进程退出

 if (fork() > 0)  
{exit(0);
}

子进程变成孤儿进程,被init进程收养  

子进程在后台运行

(2)子进程创建新会话

setsid函数:
 

#include <unistd.h>pid_t setsid(void);

成功:返回调用进程的会话ID;失败:-1,设置errno。

作用:用于创建一个新的会话,并将调用进程设置为这个新会话的领导进程(session leader),同时也是一个新进程组的组长。这使得进程完全脱离原始的控制终端,而且它的子进程将成为这个新会话和进程组的成员
调用了setsid函数的进程,既是新的会长,也是新的组长;

if(setsid()<0)
{perror("setsid:");exit(-1);
}

此时

子进程成为新的会话组长  

子进程脱离原先的终端

(3)更改当前工作目录

守护进程一直在后台运行,其工作目录不能被卸载要具有稳定性,因此最好重新设定一个稳定的工作目录;

chdir("/");
chdir("/tmp");

(4)重设文件权限掩码

umask() 是一个用于设置文件创建权限掩码的系统调用函数。当进程创建新文件或目录时,会根据当前的文件创建权限掩码来确定新文件的权限;

if(umask(0)<0)
{exit(-1);
}

 文件权限掩码设置为0;

只影响当前进程创建的新文件的权限;

(5)关闭打开的文件描述符

在脱离终端控制后,stdin / stdout / stderr无法再使用,所以需要把这三个的文件描述符关闭,标准输入(0)、标准输出(1)、和标准错误(2)

int  i;
for(i=0; i<3; i++) 
{close(i); 
}

 关闭所有从父进程继承的打开文件  

已脱离终端,stdin / stdout / stderr无法再使用

(6)步骤总结

第一步:用exit()将父进程退出,使子进程成为孤儿进程被init进程收养;
第二步:子进程利用setsid()函数创建新的会话,脱离原来的终端,成为会话组长;
第三步:使用chdir()更改工作的目录;
第四步:使用umask()重设文件权限掩码;
第五步:关闭文件描述符。
第一步可用nohup xxx  & 命令进行,但是不推荐;
第一二步是必须完成的,后面是根据自己的实际情况进行的。

4.守护进程—示例

 创建守护进程,每隔1秒将系统时间写入文件time.log

#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>int main(int argc, const char *argv[])
{pid_t pid;FILE *fp;time_t t;int i;if((pid = fork())<0){perror("fork");exit(-1);}else if(pid>0){exit(0);}setsid();umask(0);chdir("/tmp");close(0);close(1);close(2);if((fp = fopen("time.log","a")) == NULL){perror("fopen");exit(-1);}while(1){time(&t);fprintf(fp,"%s\n",ctime(&t));fflush(fp);sleep(1);}return 0;
}

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

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

相关文章

2024年3月Scratch图形化编程等级考试(二级)真题试卷

2024年3月Scratch图形化编程等级考试&#xff08;二级&#xff09;真题试卷 选择题 第 1 题 默认小猫角色&#xff0c;Scratch运行程序后&#xff0c;舞台上出现的图形是&#xff1f;&#xff08; &#xff09; A. B. C. D. 第 2 题 下列哪个Scratch选项可以使虫子移到…

Banana Pi 推出采用瑞芯微 RK3576芯片设计开源硬件:BPI-M5 Pro

Banana Pi BPI-M5 Pro采用第二代8nm高性能AIOT平台瑞芯微RK3576&#xff0c;拥有6 TOPS算力NPU&#xff0c;支持最高32GB大内存。支持8K视频编解码&#xff0c;提供双千兆网口、WiFi 6 & BT5、多种视频输出等丰富接口。兼容多种操作系统&#xff0c;适用于基于ARM的PC、边缘…

网盘——移动文件

本文主要讲解网盘文件操作部分的移动文件&#xff0c;具体步骤如下&#xff1a; 目录 1、实施步骤&#xff1a; 2、代码实现 2.1、在book里面添加移动文件的按钮 2.2、将他添加到界面 2.3、添加移动文件的槽函数 2.4、关联槽函数 2.5、在book中添加成员函数&#xff0c…

【opencv4.8.1 源码编译】windows10 OpenCV 4.8.1源码编译并实现 CUDA 12加速

Windows 下使用 CMake3.29.2 Visual Studio 2022 编译 OpenCV 4.8.1 及其扩展模块cuda12.0teslaT4显卡 记录自己在编译时踩过的坑&#xff0c;避免下次再犯或者给有需要的人。 在实际使用中&#xff0c;如果是对处理时间要求比较高的场景&#xff0c;使用OpenCV处理图片数据很…

锂电池SOH预测 | 基于CNN的锂电池SOH预测(附matlab完整源码)

锂电池SOH预测 锂电池SOH预测完整代码锂电池SOH预测 锂电池的SOH(状态健康度)预测是一项重要的任务,它可以帮助确定电池的健康状况和剩余寿命,从而优化电池的使用和维护策略。 SOH预测可以通过多种方法实现,其中一些常用的方法包括: 容量衰减法:通过监测电池的容量衰减…

微图乐 多种装B截图一键制作工具(仅供娱乐交流)

软件介绍 采用exe进程交互通信。全新UI界面&#xff0c;让界面更加清爽简约。支持zfb、VX、TX、Yin行、Dai款、游戏等图片生成&#xff0c;一键超清原图复制到剪辑板&#xff0c;分享给好友。适用于提高商家信誉度&#xff0c;产品销售额度。装逼娱乐&#xff0c;用微图乐。图…

数据结构(十)----图

目录 一.图的概念 1.图的定义 2.图的类别 3.图的性质 4.几种特殊形态的图 二.图的存储结构 1.邻接矩阵&#xff08;顺序存储&#xff09; 2.邻接表&#xff08;顺序链式存储&#xff09; 3.十字链表 4.邻接多重表 四.图的遍历 1.广度优先遍历&#xff08;BFS&#…

STM32 F103C8T6学习笔记17:类IIC通信(SMBus协议)—MLX90614红外非接触温度计

今日学习配置MLX90614红外非接触温度计 与 STM32 F103C8T6 单片机的通信 文章提供测试代码讲解、完整工程下载、测试效果图 本文需要用到的大概基础知识&#xff1a;1.3寸OLED配置通信显示、IIC通信、 定时器配置使用 这里就只贴出我的 OLED驱动方面的网址链接了&#xff1a…

Qt在任务栏图标和系统托盘图标上显示红点

在任务栏图标上显示红点 关键类&#xff1a;QWinTaskbarButton #include <QWinTaskbarButton>QPointer<QWinTaskbarButton> taskbarBtn nullptr; if (!taskbarBtn) {taskbarBtn new QWinTaskbarButton(window);taskbarBtn->setWindow(window->windowHand…

3.【Orangepi Zero2】超声模块ultrasonic(HC-SR04)

超声模块ultrasonic&#xff08;HC-SR04&#xff09; HC-SR04 超声波距离传感器如何工作&#xff1f;程序实现初始化超声波启动超声波获取距离整合代码 HC-SR04 超声波距离传感器如何工作&#xff1f; 当Trig引脚设置为高电平达 10s 时&#xff0c;超声波距离传感器开始工作。…

Spring - 9 ( 10000 字 Spring 入门级教程 )

一&#xff1a; MyBatis XML 配置文件 Mybatis 的开发有两种方式&#xff1a; 注解XML 我们已经学习了注解的方式, 接下来我们学习 XML 的方式 MyBatis XML 的方式需要以下两步: 配置数据库连接字符串和 MyBatis写持久层代码 1.1 配置连接字符串和 MyBatis 此步骤需要进…

InfiniFlow 創始人兼CEO張穎峰確認出席“邊緣智能2024 - AI開發者峰會”

隨著AI技術的迅猛發展&#xff0c;全球正逐步進入邊緣計算智能化與分布式AI深度融合的新時代&#xff0c;共同書寫著分布式智能創新應用的壯麗篇章。邊緣智能&#xff0c;作為融合邊緣計算和智能技術的新興領域&#xff0c;正逐漸成為推動AI發展的關鍵力量。借助分布式和去中心…

C++ 函数 参数与返回值

#一 参数与返回值 回顾文件读数据功能 文件读数据 1函数参数传值调用过程 将函数调用语句中的实参的一份副本传给函数的型材。 简单的值的传递&#xff0c;实参的值没有发生变化。 2 函数参数传值调用过程 传地址调用 将变量的地址传递给函数的形参 形参和实参指向了同…

C语言 基本数据类型及大小

一、基本数据类型 1.整型int 整型的关键字是int&#xff0c;定义一个整型变量时&#xff0c;只需要用int来修饰即可。也分为短整型和长整型。 2.浮点型 浮点型又分单精度浮点型float和双精度浮点型double。 3.字符型char 前面的整型和浮点型都是用于存放数字。字符型&…

docker部署nginx并实现https

文章目录 docker部署nginx并实现https1、服务器环境2、安装docker3、准备证书4、准备nginx配置文件和dockerfile文件5、创建nginx镜像与容器6、验证访问 docker部署nginx并实现https 1、服务器环境 [rootliuyanfen12 ~]#systemctl stop firewalld [rootliuyanfen12 ~]#setenf…

【c++】继承学习(二):探索 C++ 中派生类的默认机制与静态成员共享

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 目录 1.派生类的默认成员函数2.继承与友元3.继承与静态成员 朋友们大家好&#xff0c;本篇文章我们来学习继承的第二部分 1.派生类的默认成员函数 来看下面的类&#xff1a; class Person…

Delta lake with Java--分区表

今天尝试一下将昨天的数据操作建立的表换成分区表&#xff0c;参考Delta Lake Up and Running做法用分区表的方式来更新数据。还要比较一下分区表的查询与非分区表的查询&#xff0c;结果显示分区表的查询速度要比非分区表要快。直接上代码&#xff1a; import io.delta.table…

发表博客之:transformer 架构 推理时候运算流程详细讲解,以及变长推理支持,小白都可以看得懂,AI推理工程师必备技能!

文章目录 [发表博客之&#xff1a;transformer 架构 推理时候运算流程详细讲解&#xff0c;以及变长推理支持&#xff0c;小白都可以看得懂&#xff0c;AI推理工程师必备技能&#xff01;](https://cyj666.blog.csdn.net/article/details/138439826)总结一下高性能变长推理 发表…

定点乘除法

目录 一、定点乘法 1.串行乘法器 2.并行乘法器 二、定点除法 1.笔算除法 2.机器除法 一、定点乘法 1.串行乘法器 1.符号位单独处理&#xff0c;两数的符号位按异或运算得到&#xff0c;而乘积的数值部分则是两个正数相乘之积。 2.过程 &#xff08;1&#xff09; 由乘…

「2024年」前端开发常用工具函数总结 TypeScript

前言 在前端开发中&#xff0c;工具函数是提高代码复用率、保持代码整洁和增加开发效率的关键。使用 TypeScript 编写工具函数不仅可以帮助开发者捕捉到更多的类型错误&#xff0c;还可以提供更清晰的代码注释和更智能的代码补全。下面是一些在 TypeScript 中常用的前端开发工…