从零开始学习Linux(6)----进程控制

1.环境变量

        环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数,我们在编写C/C++代码时,链接时我们不知道我们链接的动态静态库在哪里,但可以连接成功,原因是环境变量帮助编译器进行查找,环境变量通常具有某些特殊用途,还有在系统当中中通常具有全局特性。

        环境变量不是一个而是一堆,彼此之间其实没有关系。

        环境变量一般是系统内置的具有特殊作用的变量。

        定义变量的本质,其实是开辟空间,在运行期间我们的程序也能开辟空间,操作系统/bash是用C语言写的程序,它能在运行中开辟空间,系统的环境变量,本质就是系统自己开辟空间,给他名字和内容即可。

1.命令行参数

int main(int argc,char *argv[],char *env[])

#include <stdio.h>
#include <string.h>
int main(int argc,char *argv[])
{if(argc!=2){printf("Usage:\n\t%s -number[1-3]\n",argv[0]);return 1;}if(strcmp("-1",argv[1])==0){printf("function 1\n");}                                                     else if(strcmp("-2",argv[1])==0){printf("function 2\n");}else if(strcmp("-3",argv[1])==0){printf("function 3\n");}else{printf("unknown!\n");}
}

        我们可以通过不同的选项,让我们的同一个程序执行它内部不同的功能。命令行参数时Linux指令的基础。

        在上面的演示中,为什么我们不能像ls命令一样执行而是./的方式来执行,这时需要将你的程序所在的路径添加到环境变量中。

        指令env查看系统所有环境变量。命令行参数env[]中存放的也是系统所有环境变量,export命令导入环境变量。环境变量是可以被子进程继承下去的!(方式1),环境变量具有全局属性,会被所有的子进程继承。还可通过第三方变量environ,和getenv方法来获取。本地变量只能bash内部有效。

2.程序地址空间

        子进程按照父进程为模版,父子并没有对变量进行任何修改,如果子进程先修改,完成之后父进程再读取,我们发现父子进程输出地址是一致的,但是变量内容不一样,所以:

        变量内容不一样,所以父子进程输出的变量绝对不是同一个变量但地址值是一样的,说明,该地址绝对不是物理地址! 在Linux地址下,这种地址叫做 虚拟地址,我们在用C/C++语言所看到的地址,全部都是虚拟地址!物理地址,用户一概看不到,由OS统一管理。OS必须负责将 虚拟地址 转化成 物理地址 。
        同一个变量,地址相同,其实是虚拟地址相同,内容不同其实是被映射到了
不同的物理地址。

1.什么是地址空间

        进程地址空间,每一个进程,都会存在一个进程地址空间,32【0,4GB】;进程地址空间是数据结构,就是特点数据结构的对象。区域划分本质就是区域内的各个地址,都可以使用,我们的地址空间不具备对我们的代码和数据的保存能力,将地址空间上的地址转化到物理内存中,给我们的进程提供一张映射表---页表。

2.为什么要有地址空间+页表

        将物理内存从无序变有序,让进程以统一的视角看待内存。

        将进程管理和内存管理进行解耦合。

        地址空间+页表是保护内存安全的重要手段。

​​​​​​ 1.写时拷贝

        进程调用fork,当控制转移到内核中的fork代码后,内核做:

  • 分配新的内存块和内核数据结构给子进程
  • 将父进程部分数据结构内容拷贝至子进程
  • 添加子进程到系统进程列表当中
  • fork返回,开始调度器调度

        通常,父子代码共享,数据也是共享的,当任意一方试图写入,便以写时拷贝的方式各自一份副本。所以,fork之前父进程独立执行,fork之后,父子两个执行流分别执行。

3.进程终止

        main函数的返回值叫做进程的退出码,一般0,表示进程执行成功,非零表示失败,不同的数字表示不同的错误原因。可以通过echo $?查看进程退出码。

        错误码转化为错误描述:1.可以使用系统自带的。2.自定义。除了进程退出,函数退出,我们怎么知道函数的执行情况。函数有返回值,调用函数,我们通常想看到两种结果:1.函数的执行结果。2.函数的执行情况--成功,失败,原因。

        进程退出的场景就三种:1.代码执行完,结果是正确的。2.代码执行完,结果是不正确的。3.进程代码没有执行完,进程出异常了(是进程收到了异常信号,每个信号都有不同的编号,不同的信号编号表明异常的原因)。

        任何进程最终的执行情况,我们可以使用两个数字表明具体执行的情况。

    exit就是用来终止进程的。exit(退出码)在我们的进程代码中,任意地方调用exit,都表示进程退出,exit会支持刷新缓冲区,_exit不支持,我们之前所说的缓冲区绝对不是操作系统里面的缓冲区,而是上层的库的缓冲区。

4.进程等待

  • 之前讲过,子进程退出,父进程如果不管不顾,就可能造成‘僵尸进程’的问题,进而造成内存泄漏。
  • 另外,进程一旦变成僵尸状态,那就刀枪不入,“杀人不眨眼”的kill -9 也无能为力,因为谁也没有办法杀死一个已经死去的进程。

1.父进程通过wait方式,回收子进程的资源(必然)

2.通过wait方式,获取子进程的退出信息(可选的)

wait默认会进行阻塞等待,等待任意一个子进程,返回值>0:等待成功,等待子进程的pid,<0:等待失败。

pid_t wait(int*status);
返回值:
成功返回被等待进程pid,失败返回-1。
参数:
输出型参数,获取子进程退出状态,不关心则可以设置成为NULL
waitpid
pid_ t waitpid(pid_t pid, int *status, int options);
返回值:
        当正常返回的时候waitpid返回收集到的子进程的进程ID;
        如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;
        如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;
参数:
        pid:
                Pid=-1,等待任一个子进程。与wait等效。
                Pid>0.等待其进程ID与pid相等的子进程。
        status:
                WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)
                WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码)
        options:
                WNOHANG: 若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若正常结束,则返回该子进 程的ID。
  • 如果子进程已经退出,调用wait/waitpid时,wait/waitpid会立即返回,并且释放资源,获得子进程退出信息。
  • 如果在任意时刻调用wait/waitpid,子进程存在且正常运行,则进程可能阻塞。
  • 如果不存在该子进程,则立即出错返回。
获取子进程status
  • wait和waitpid,都有一个status参数,该参数是一个输出型参数,由操作系统填充。
  • 如果传递NULL,表示不关心子进程的退出状态信息。
  • 否则,操作系统会根据该参数,将子进程的退出信息反馈给父进程。
  • status不能简单的当作整形来看待,可以当作位图来看待(只研究status低16比特位.

5.进程程序替换

1.替换原理

        什么是程序替换:

                a.我们的程序,只能执行我们的代码。

                b.如果我们创建的子进程,想执行其他程序的代码呢?

        在替换过程中,有没有创建新的进程???没有!

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

2.替换函数

        有六种以exec开头的函数,统称为exec函数:

#include <unistd.h>
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[]);
        这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回。
        如果调用出错则返回-1
        所以exec函数只有出错的返回值而没有成功的返回值
l(list) : 表示参数采用列表
v(vector) : 参数用数组
p(path) : 有p自动搜索环境变量PATH
e(env) : 表示自己维护环境变量
        更改为多进程版本,我们为什么要这么做:父进程能得到执行结果。
        替换为什么没有影响父进程:进程具有独立性,替换的时候,发生写时拷贝。
默认可以通过地址空间继承的方式,让所以得子进程拿到环境变量
        进程程序替换,不会替换环境变量数据
1.如果我们想让子进程继承全部的环境变量,直接能拿到
2.如果单纯的新增呢?putenv
3.如果我想设置全新的环境变量给子进程呢?

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

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

相关文章

【爬虫之scrapy框架——尚硅谷(学习笔记two)--爬取电影天堂(基本步骤)】

爬虫之scrapy框架--爬取电影天堂——解释多页爬取函数编写逻辑 &#xff08;1&#xff09;爬虫文件创建&#xff08;2&#xff09;检查网址是否正确&#xff08;3&#xff09;检查反爬&#xff08;3.1&#xff09; 简写输出语句&#xff0c;检查是否反爬&#xff08;3.2&#x…

电力系统潮流计算的计算机算法(一)——网络方程、功率方程和节点分类

本篇为本科课程《电力系统稳态分析》的笔记。 本篇为这一章的第一篇笔记。下一篇传送门。 实际中的大规模电力系统包含成百上千个节点、发电机组和负荷&#xff0c;网络是复杂的&#xff0c;需要建立复杂电力系统的同一潮流数学模型&#xff0c;借助计算机进行求解。 简介 …

免费Premiere模板,几何图形元素动画视频幻灯片模板素材下载

Premiere Pro模板&#xff0c;几何图形元素动画视频幻灯片模板 &#xff0c;组织良好&#xff0c;易于自定义。包括PDF教程。 项目特点&#xff1a; 使用Adobe Premiere Pro 2021及以上版本。 19201080全高清。 不需要插件。 包括帮助视频。 免费下载&#xff1a;https://prmu…

Fabric实现多GPU运行

官方的将pytorch转换为fabric简单分为五个步骤&#xff1a; 步骤 1&#xff1a; 在训练代码的开头创建 Fabric 对象 from lightning.fabric import Fabricfabric Fabric() 步骤 2&#xff1a; 如果打算使用多个设备&#xff08;例如多 GPU&#xff09;&#xff0c;就调用…

高级个人主页

高级个人主页 效果图部分代码领取源码下期更新预报 效果图 部分代码 <!DOCTYPE html> <html lang"en"><head><meta charset"utf-8" name"viewport" content"widthdevice-width, initial-scale1, maximum-scale1, use…

ESP32重要库示例详解(四):获取NTP时间之time库

在物联网项目中&#xff0c;时间同步和管理是至关重要的功能之一&#xff0c;特别是在需要执行定时任务或记录事件时间戳的场景下。Arduino平台通过其内置的<time.h>库提供了强大的时间处理能力&#xff0c;使得开发者能够方便地与网络时间协议&#xff08;NTP&#xff0…

PDF文件转换为CAD的方法

有时候我们收到一个PDF格式的设计图纸&#xff0c;但还需要进行编辑或修改时&#xff0c;就必须先将PDF文件转换回CAD格式。分享两个将PDF转换回CAD的方法&#xff0c;一个用到在线网站&#xff0c;一个用到PC软件&#xff0c;大家根据情况选择就可以了。 ☞在线CAD网站转换 …

css超出部分省略(单行、多行,多种方法实现)

HTML <p class"text">这是一行测试数据,这是一行测试数据,这是二行测试数据,这是一行测试数据,这是三行测试数据,这是四行测试数据</p>1.单行 .text{width: 200px;border: 1px solid #000000;white-space: nowrap; /* 控制元素不换行 */overflow: hi…

Django图书馆综合项目-学习(2)

接下来我们来实现一下图书管理系统的一些相关功能 1.在书籍的book_index.html中有一个"查看所有书毂"的超链接按钮&#xff0c;点击进入书籍列表book_list.html页面. 这边我们使用之前创建的命名空间去创建超连接 这里的book 是在根路由创建的namespacelist是在bo…

6. RedHat认证-基于公钥的认证方式

6. RedHat认证-基于公钥的认证方式 主要学习客户端访问服务端的时候&#xff0c;免密登录这一方式 注意: 免密登录只是基于公钥认证的一个附带属性(基于公钥认证的方式更加安全&#xff0c;防止黑客暴力破解) 第一步&#xff1a;将客户端生成的秘钥传送到服务器 在客户端通过…

2024中国(厦门)国际医用消毒及感控设备展览会

2024中国&#xff08;厦门&#xff09;国际医用消毒及感控设备展览会 2024 China (Xiamen) International Medical Disinfection And Infection Control Exhibition 致力于打造医用消毒及感控设备产业采购一站式平台 时 间&#xff1a;2024年11月1-3日 November 1-3, 2024 …

一文扫盲(13):电商管理系统的功能模块和设计要点

电商管理系统是一种用于管理和运营电子商务平台的软件系统。它提供了一系列功能模块&#xff0c;帮助企业进行商品管理、订单管理、会员管理、营销推广、数据分析等工作。本文将从以下四个方面介绍电商管理系统。 一、什么是电商管理系统 电商管理系统是一种集成了各种功能模块…

免费的集成组件有哪些?

集成组件是指将多个软件或系统进行整合&#xff0c;以实现更高效、更可靠的数据处理和管理。在数据管理和分析领域&#xff0c;集成组件是不可或缺的工具之一。 在当今高度信息化的时代&#xff0c;集成组件在各行各业的应用中扮演着举足轻重的角色。集成组件能够将不同来源的…

企业安全必备利器:专业级加密软件介绍

随着信息技术的迅猛发展&#xff0c;数据安全问题日益凸显&#xff0c;专业级加密软件应运而生&#xff0c;成为保护数据安全的重要工具。本文将对专业级加密软件进行概述&#xff0c;分析其特点、应用场景及分享。 一、专业级加密软件概述 专业级加密软件是指那些采用高级加密…

三分钟了解计算机网络核心概念-数据链路层和物理层

计算机网络数据链路层和物理层 节点&#xff1a;一般指链路层协议中的设备。 链路&#xff1a;一般把沿着通信路径连接相邻节点的通信信道称为链路。 MAC 协议&#xff1a;媒体访问控制协议&#xff0c;它规定了帧在链路上传输的规则。 奇偶校验位&#xff1a;一种差错检测方…

uniapp怎么使用jsx

安装vitejs/plugin-vue-jsx npm install vitejs/plugin-vue-jsx -Dvite.config.js配置 import { defineConfig } from "vite"; import uni from "dcloudio/vite-plugin-uni"; import vueJsx from vitejs/plugin-vue-jsxexport default defineConfig({plu…

upload-labs靶场通关详解(1-15)

1.pass-01 查看源代码 是js&#xff0c;属于前端校验 可以通过禁用js来上传文件 2.pass-02 根据提示是MIME绕过 MIME&#xff1a;是设定某种扩展名的文件 用一种应用程序来打开的方式类型&#xff0c;当该扩展名文件被访问的时候&#xff0c;浏览器会自动使用指定应用程序来…

冯喜运:5.14黄金价格空头延续反弹空,原油走势分析实时操作

【黄金消息面分析】&#xff1a;周二&#xff08;5月14日&#xff09;亚洲时段&#xff0c;现货黄金窄幅震荡&#xff0c;目前交投于2342美元/盎司。金价周一因获利了结下跌1%&#xff0c;收报2336.10美元/盎司&#xff0c;投资者等待本周的关键通胀数据为今年美国降息提供更多…

使用Subtitle edit合成双语字幕

有的时候从网上下载的字幕有单独的中文版和英语版&#xff0c;但是没有中英文一起的双语字幕&#xff1a; 后缀为chs的是中文简体后缀为cht的是中文繁体后缀为eng的是英文 如果我们在电脑端上可以直接用potplayer添加副字幕来实现双语&#xff0c;但是如果是别的播放器&#…

多线程·线程状态

目录 1.等待一个线程 join 2.休眠当前线程 3.线程的所有状态 4.线程的状态转换 1.等待一个线程 join 有些场景&#xff0c;我们需要控制线程的执行顺序&#xff0c;这时候就需要用到 join 了 比如&#xff1a;把大象装进冰箱要几步&#xff1f; 第一步&#xff1a;打开冰…