IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux系统编程:进程控制1 -> 正文阅读

[系统运维]Linux系统编程:进程控制1

🌍Linux系统编程2:进程控制

🌳fork函数
🍀作用与定义方式
作用:创建一个子进程。 定义:pid_t fork(void); 失败返回-1;成功返回0:① 父进程返回子进程的 ID(非负) ②子进程返回 0;pid_t类型表示进程 ID,但为了表示-1,它是有符号整型(0不是有效进程 ID,init最小为 1) ;

🍀 父子进程相同:

刚fork后。 data段、text段、堆、栈、环境变量、全局变量、宿主目录位置、进程工作目录位置、信号处理方式相同。

🍀父子进程不同:

.进程id、返回值、各自的父进程、进程创建时间、闹钟、未决信号集不同。

🍀父子进程共享:
1、全局变量而言:读时共享、写时复制;
2、文件描述符 ;
3、 mmap映射区。

代码实现创建子进程在这里插入图片描述
运行结果:
在这里插入图片描述
🍀获取父子进程的两个函数

getpid();//获取当前进程ID
getppid();//获得父进程ID

编程实现:
在这里插入图片描述
运行结果:

在这里插入图片描述
观察运行结果:
观察子进程输出:子进程 pid=3140,父进程 pid=1630;
观察父进程输出:子进程pid=3140,自己进程pid=3139;父进程pid=2911。
出现的问题:从父进程返回的子进程和子进程的pid一样,子进程却说自己的父进程为pid=1630,父进程自己的pid=3139。
原因:父进程先死亡,子进程成为孤儿被收到了为pid=1630的孤儿院。

修改代码:给与父进程一个sleep(1)命令,子进程先于父进程死亡。
在这里插入图片描述
运行结果:
在这里插入图片描述
此时运行结果不再出现上述问题。

🍀循环创建多个子进程
一次 fork函数调用可以创建一个子进程。那么创建 N个子进程应该怎样实现呢?
简单想,for(i = 0; i < n; i++) { fork() } 即可。但这样创建的是 N个子进程吗?
在这里插入图片描述
从上图我们可以很清晰的看到,当 n为 3时候,循环创建了(2^n)-1个子进程,而不是 N的子进程。需要在循环的过程,保证子进程不再执行 fork ,因此当(fork() == 0)时,子进程应该立即 break;才正确。

编程实现:
在这里插入图片描述
运行结果:在这里插入图片描述
出现了问题:进程多了一个,而且不是按顺序来的。这里多出的一个,是父进程,因为父进程才有i=5跳出循环这一步。所以,对父进程进行判定并处理
修改代码如下:
在这里插入图片描述
运行结果:
在这里插入图片描述
现在还有两个问题:

  1. 一个就是包括父进程在内的所有进程不是按顺序出现,多运行几次,发现是随机序列出现的。这是要因为,对操作系统而言,这几个子进程几乎是同时出现的,它们和父进程一起争夺cpu,谁抢到,谁打印,所以出现顺序是随机的。
  2. 第二问题就是终端提示符混在了输出里,这个是因为,loop_fork(本程序名)是终端的子进程,一旦loop_fork执行完,终端就会打印提示符。就像之前没有子进程的程序,一旦执行完,就出现了终端提示符。这里也就是这个道理,loop_fork执行完了,终端提示符出现,然而loop_fork的子进程还没执行完,所以输出就混在一起了。解决方法如下让父进程加个sleep函数。让父进程在所有子进程结束后运行
    在这里插入图片描述
    .运行结果:在这里插入图片描述

🌳父子进程共享哪些内容
上面已经提到
1、父子进程相同:
刚fork后。 data段、text段、堆、栈、环境变量、全局变量、宿主目录位置、进程工作目录位置、信号处理方式。
父子进程不同:
进程id、返回值、各自的父进程、进程创建时间、闹钟、未决信号集。
父子进程共享:
全局变量:读时共享、写时复制;
文件描述符; mmap映射区。

🌳父子进程gdb调试

设置父进程调试路径:set follow-fork-mode parent (默认)
设置子进程调试路径:set follow-fork-mode child

注意,一定要在fork函数调用之前设置才有效。

🌳exec函数族
fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种 exec函数以执行另一个程序。当进程调用一种 exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用 exec并不创建新进程,所以调用 exec前后该进程的 id并未改变。

将当前进程的.text、.data替换为所要加载的程序的.text、.data,然后让进程从新的.text第一条指令开始执行,但进程 ID不变,换核不换壳。

其实有六种以 exec开头的函数,统称 exec函数:
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[]);

🍀execlp函数
加载一个进程,借助 PATH环境变量
int execlp(const char *file, const char *arg, …); 成功:无返回;失败:-1
参数 1:要加载的程序的名字。该函数需要配合 PATH环境变量来使用,当 PATH中所有目录搜索后没有参数 1则出错返回。 该函数通常用来调用系统程序。如:ls、date、cp、cat等命令。

代码示例:通过execlp让子进程执行ls命令
在这里插入图片描述

运行结果
在这里插入图片描述
下面使用execl来让子程序调用自定义的程序。
int execl(const char *path, const char *arg, …)
这里要注意,和execlp不同的是,第一个参数是路径,不是文件名。这个路径用相对路径和绝对路径都行。
调用的代码如下

子进程要调用的程序:
在这里插入图片描述
exec程序:
在这里插入图片描述
运行结果:
在这里插入图片描述

注:以上内容均从总结于网上学习资源。

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-03-15 23:07:58  更:2022-03-15 23:13:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 2:35:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码