【Linux】孤儿进程 | 环境变量 | 命令行参数 | 进程优先级
文章目录
- 1. 孤儿进程
- 2. 环境变量
- 1. PATH环境变量
- 证明ls是系统指令
- 修改自己写的可执行程序对应路径
- 2. env——查看系统环境变量
- 3. 获取环境变量
- envp
- environ
- getenv 函数获取 (主流)
- 4. 总结
- 3 . 命令行参数
- 理解命令行参数
- 4. 进程优先级
- 优先级与权限的区分
- 为什么会有优先级?
- 查看系统进程的优先级
- 调整进程优先级
1. 孤儿进程
如果父进程一直存在,子进程先退出了,父进程对子进程退出不管不顾,会出现什么样问题么?
创建makefile并输入以下内容
mytest:test.c2 gcc -o $@ $^ 3 .PHONY:clean4 clean:5 rm -f mytest
mytest 属于 目标文件
test.c 属于 依赖文件列表
$@代表目标文件
$^ 代表依赖文件列表
创建test.c并输入以下内容
#include<stdio.h>2 #include<unistd.h>3 int main()4 {5 pid_t id=fork();6 if(id==0)7 {8 //子进程9 while(1)10 {11 printf("我是子进程,我的pid是:%d,我的ppid是%d",getpid(),getppid());12 sleep(1); 13 } 14 15 }16 else if(id>0)17 {18 //父进程19 int count=0;//父进程只运行10次20 while(1) 21 { 22 printf("我是父进程,我的pid是:%d,我的ppid是%d",getpid(),getppid());23 sleep(1); 24 if(count--<=0) 25 { 26 break; 27 } 28 } 29 } 30 }
- 使子进程一直循环,父进程只运行10次
复制SSH渠道,创建终端2,在保证终端1mytest运行的情况下,在终端2中输入指令
while :; do ps axj | head -1 && ps axj | grep mytest | grep -v grep ; sleep 1; echo "---------"; done
创建终端方法点击查看
---------PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
17835 27831 27831 17835 pts/0 27831 S+ 1002 0:00 ./mytest
27831 27832 27831 17835 pts/0 27831 S+ 1002 0:00 ./mytest
当父子进程刚开始共存时,两者状态都是S+
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND1 27832 27831 17835 pts/0 17835 S 1002 0:00 ./mytest
当父进程运行结束后,子进程状态为S
正常来说,若父子进程中子进程结束,父进程要接收子进程的退出码结果,所以子进程处于僵尸状态
但是 父子进程中父进程结束,为什么父进程没有进入僵尸状态呢?
- 当前退出的进程27831的父进程是bash,bash会自动回收27831的僵尸状态
- 原本进程27832的父进程是27831,当27831进程结束后,27832的父进程变为1
- 如果父子进程中父进程先退出,而子进程没退出,子进程在父进程退出后,要被1号进程领养,1号进程称为操作系统,而被领养的进程称为孤儿进程
- 如果不领养,子进程后续退出,就无人回收了
2. 环境变量
在操作系统当中由系统在开机之后帮我们维护的一些系统运行时的动态参数
我们自己写的代码,编译之后,运行的时候,为什么要带 ./ ?
- . 代表当前路径 , / 代表路径分割符 . / 可执行程序说明使用相对路径的方式来定位可执行程序
- 自己写的可执行程序和系统自带的指令之间没有区别
那为什么运行系统的指令不需要 ./ ?
- 因为系统指令的路径在环境变量中
1. PATH环境变量
echo 作为打印字符串的一条命令
[yzq@VM-8-8-centos ~]$ echo abcd
abcd
echo $PATH 查看环境变量PATH
[yzq@VM-8-8-centos ~]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/mydir/.local/bin:/home/mydir/bin
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/mydir/.local/bin:/home/mydir/bin
是以冒号作为分隔符,可以分割出来若干子路径
- pwd、ls指令,会在环境变量所指明的若干路径中一个个去找,找到就会自动执行,不用带路径
- 而我们自己实现的可执行程序,路径不在环境变量里,所以必须由用户自动指明它的路径
证明ls是系统指令
使用which
指令,搜索特定指令所对应的路径
[yzq@VM-8-8-centos my]$ which ls
alias ls='ls --color=auto'/usr/bin/ls
ls的路径为 /usr/bin/ls
环境变量是从左到右,一条一条去查找,只要找到就停下来
ls指令在环境变量的usr/bin
路径下,说明 ls 指令不用带路径
修改自己写的可执行程序对应路径
修改自己写的可执行程序的路径,让其不用添加路径即可运行
创建test.c文件
#include<stdio.h>2 int main()3 {4 printf("hello"); 5 }
输入 gcc -o testc test.c
,生成testc可执行程序
输入 which testc
,查询testc的路径
[yzq@VM-8-8-centos my]$ which testc
/usr/bin/which: no testc in (/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/mydir/.local/bin:/home/mydir/bin)
说明 testc路径不在环境变量中
使用pwd
,查询当前testc的路径,
输入 export PATH=$PATH: 当前路径
,将testc的路径新增到到环境变量中
[yzq@VM-8-8-centos my]$ pwd
/home/mydir/my
[yzq@VM-8-8-centos my]$ export PATH=$PATH:/home/mydir/my
[yzq@VM-8-8-centos my]$ testc
hello
直接 使用 testc ,就运行可执行程序
2. env——查看系统环境变量
使用 env ,会出现如下环境变量
这些环境变量都是用户登录的时候设置好的,都是kv的
输入 echo $HOSTNAME
显示当前机器 名字
[yzq@VM-8-8-centos ~]$ echo $HOSTNAME
VM-8-8-centos
输入 echo $SHELL
显示当前所使用的shell
[yzq@VM-8-8-centos ~]$ echo $SHELL
/bin/bash
输入 echo $HOME
,当前为普通用户
[yzq@VM-8-8-centos ~]$ echo $HOME
/home/mydir
HOME环境变量表示当前用户所对应的家目录
切换成root用户后, 此时对应root目录
[root@VM-8-8-centos mydir]# echo $HOME
/root
对于不同登录的人,同一个环境变量里面放的不同的内容,所以环境变量是针对特定的人在特定的场景使用的
3. 获取环境变量
envp
main函数可以带3个参数分别为 int argc 和 char*argv [ ] 和char * envp[ ] (环境变量表)

- char* envp[ ]是一个指针数组,char类型指针都指向字符串,但最后无效内容必须以NULL结尾
创建test.c文件
#include<stdio.h>2 #include<unistd.h>3 int main(int argc,char*argv[],char*envp[])4 {5 int i=0;6 for(i=0;envp[i];i++)7 {8 printf("envp[%d]->%s\n",i,envp[i]);9 } 10 }
创建makefile
mytest:test.c2 gcc -o mytest test.c3 .PHONY:clean4 clean:5 rm -f mytest
输入 make ,使用./mytest 执行可执行程序

发现envp是一张传递给当前进程的环境变量表
char类型指针指向环境变量字符串
environ
若main函数不传参数,还想要拿到环境变量,可以使用 environ
修改test.c文件
#include<stdio.h>2 #include<unistd.h>3 int main()4 {5 extern char** environ;//声明6 int i=0;7 for(i=0;environ[i];i++)8 {9 printf("environ[%d]->%s\n",i,environ[i]);10 } 11 }
使用make, ./mytest执行可执行程序后

使用environ 也可以拿到所有环境变量
getenv 函数获取 (主流)
char* getenv(const char* name);
修改test.c文件
1 #include<stdio.h>2 #include<stdlib.h>3 #include<unistd.h>4 int main()5 {6 char*user=getenv("USER");7 if(user==NULL)8 {9 perror("getenv");10 }11 else 12 {13 printf("USER:%s\n",user);14 }15 }
输入 make, ./mytest 执行可执行程序
[yzq@VM-8-8-centos my]$ ./mytest
USER:yzq
获取到user的名称
4. 总结
- 环境变量本质就是一个内存级的一张表,这张表由用户在登录系统的时候,进行给特定用户形成属于自己的环境变量表
- 环境变量每一个都有自己的用途,有的是进行路径查找的,有的是进行身份认证的,有的是动态库查找的,有的用来进行确认当前路径的等等,每一个环境变量都有自己的应用场景,每一个元素都是kv的
环境变量对应的数据,是从系统的相关配置文件中读取进来的
使用 cd ~
,进入当前目录的主目录中
使用 ls -la
, 显示隐藏文件
这是两个shell脚本,内部包含了配置文件
3 . 命令行参数
main函数的两个参数,char* argv[]
为指针数组 ,argv为一张表,包含一个个指针,指针指向字符串
int argc
,argc为数组的元素个数
修改test.c文件
#include<stdio.h>2 #include<stdlib.h>#inlcude<string.h>3 #include<unistd.h>4 int main (int argc,char*argv[])5 {int i=0;6 for(i=0;i<argc;i++)7 {8 printf("argv[%d]->%s\n",i,argv[i]);10 }
使用make , ./mytest 执行可执行程序
[yzq@VM-8-8-centos my]$ ./mytest
argv[0]->./mytest
[yzq@VM-8-8-centos my]$ ./mytest -a
argv[0]->./mytest
argv[1]->-a
[yzq@VM-8-8-centos my]$ ./mytest -a -b
argv[0]->./mytest
argv[1]->-a
argv[2]->-b

./mytest -a -b,就是一个字符串
以空格作为分隔符,形成一个一个的子串
第一个./mytest为可执行程序,剩余的统称为参数选项
理解命令行参数
修改test.c文件
#include<stdio.h>2 #include<stdlib.h>3 #include<unistd.h>4 #include<string.h>5 void usage(const char*name)6 {7 printf("\nusage:%s-[a|b|c]\n\n",name);8 exit(0);//终止进程9 } 10 int main (int argc,char*argv[]) 11 { 12 if(argc!=2) 13 { 14 usage(argv[0]);//argv[0]代表可执行程序 } } 15 if(strcmp(argv[1],"-a")==0) 16 { 17 printf("打印目录下的文件名\n"); 18 } 19 else if(strcmp(argv[1],"-b")==0) 20 { 21 printf("打印目录下的文件的详细信息\n"); 22 } 23 else if(strcmp(argv[1],"-c")==0) 24 { 25 printf("打印目录下文件的隐藏信息\n");26 }27 else 28 {29 printf("待未开发\\n");30 }31 32 }
使用 make ,./mytest 执行可执行程序
[yzq@VM-8-8-centos my]$ ./mytestusage:./mytest-[a|b|c][yzq@VM-8-8-centos my]$ ./mytest -a
打印目录下的文件名
[yzq@VM-8-8-centos my]$ ./mytest -b
打印目录下的文件的详细信息
[yzq@VM-8-8-centos my]$ ./mytest -c
打印目录下文件的隐藏信息
[yzq@VM-8-8-centos my]$ ./mytest -d
待未开发
相当于使用ls 、ls -l 、ls -la 指令,选项以字符串形式以命令行参数传递给了程序,程序内部对选项做判断,就可使同样的ls ,携带不同的选项,就可表现不同的现象
4. 进程优先级
优先级与权限的区分
权限代表能不能的问题,优先级代表已经能,谁先谁后的问题
比如 权限:若你考完试,你能够自己去老师教室翻阅自己的卷子么,当然不能,没有权限
优先级:若你在食堂排队,你可以打饭,但是有先后顺序
为什么会有优先级?
- CPU资源有限,一般来说,一个电脑中CPU有一个或者两个,但是进程却有很多个,以少量的资源来应对多量的进程,势必就会存在多进程竞争资源的情况,只要竞争就要确认谁先谁后,确认优先级
查看系统进程的优先级
ps -l
查看当前系统的进程优先级
[yzq@VM-8-8-centos my]$ ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 R 1002 3722 17835 0 80 0 - 38324 - pts/0 00:00:00 ps
0 S 1002 17835 17834 0 80 0 - 29280 do_wai pts/0 00:00:00 bash
PRI
代表当前进程的优先级
NI
代表当前进程优先级的修正数据
UID
代表当前用户的身份标识
PRI数字值越小,优先级越高
PRI(new)=PRI(old)+NI(nice)
一般调整的是nice值,nice值取值范围是[-20-19]
调度器的作用是一碗水端平,让每一个进程有享有资源,所以不支持将一个进程的PRI调整过小,从而导致优先级过高
调整进程优先级
在test.c中修改为以下内容
#include<stdio.h>2 #include<unistd.h>3 int main()4 {5 while(1)6 {7 printf(".");8 fflush(stdout);//刷新缓冲区9 sleep(1); 10 } 11 return 0; 12 }
使用./mytest运行程序,并复制SSH渠道 创建终端2
在保证终端1mytest运行的情况下,在终端2中使用 ps -la
,找到mytest进程
[yzq@VM-8-8-centos my]$ ps -la
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 1002 8561 17835 0 80 0 - 1054 hrtime pts/0 00:00:00 mytest
0 R 1002 9135 23362 0 80 0 - 38332 - pts/1 00:00:00 ps
再次在终端2中使用 top 指令,输入 r(renice),出现如下数据
PID to renice [default pid = 7429]
在上一步输入的 ps -la
指令中查询mytest的PID

使用q退出
再次输入 ps -la指令
[yzq@VM-8-8-centos my]$ ps -la
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 1002 8561 17835 0 90 10 - 1054 hrtime pts/0 00:00:00 mytest
0 R 1002 12141 23362 0 80 0 - 38332 - pts/1 00:00:00 ps
发现刚刚修改nice值为10 ,PID值变为90
相关文章:

【Linux】孤儿进程 | 环境变量 | 命令行参数 | 进程优先级
文章目录1. 孤儿进程2. 环境变量1. PATH环境变量证明ls是系统指令修改自己写的可执行程序对应路径2. env——查看系统环境变量3. 获取环境变量envpenvirongetenv 函数获取 (主流)4. 总结3 . 命令行参数理解命令行参数4. 进程优先级优先级与权限的区分为什么会有优先级ÿ…...

Matlab字符串相关操作-拼接、格式化
常见的有三种方法:向量拼接、strcat函数和sprintf函数1、向量拼接在matlab中字符串本质上也是一个向量,可以通过矩阵运算来实现字符串的拼接,这里随便输入两个字符串a1和b1,用矩阵形式进行拼接:a1 I love;b1 Matlab…...

死磕Spring系列,SpringBoot启动流程
参考文章:SpringBoot启动流程系列讲解 参考视频:SpringBoot启动流程 吐血推荐视频:史上最完整的Spring启动流程 超级好文:SpringBoot执行原理 参考文章:SpringBoot资源接口ResourceLoader和Resource学习 参考文章&…...

关于条件变量wait操作中锁的作用
condition_variable::wait的锁 在看C Concurrency in Action 6.2.3节的线程安全队列时,其对condition_variable的使用与常规用法有点不同,我对condition_variable::wait中锁的作用产生了疑惑:它究竟是保护的谁?于是找到了 C noti…...

JUC并发编程与源码分析笔记09-原子类操作之十八罗汉增强
基本类型原子类 AtomicInteger、AtomicBoolean、AtomicLong。 常用API: public final int get();// 获取当前的值 public final int getAndSet(int newValue);// 获取当前值,并设置新值 public final int getAndIncrement();// 获取当前的值࿰…...

含分布式电源的配电网日前两阶段优化调度模型(Matlab代码实现)
👨🎓个人主页:研学社的博客💥💥💞💞欢迎来到本博客❤️❤️💥💥🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密…...

FreeRTOS的Delay函数
两个Delay函数有两个延时函数vTaskDelay:至少等待指定个数的Tick Interrupt才能变为就绪态xTaskDelayUtil:等待到指定的绝对时刻,才能变为就绪态个人感觉这两个延时函数就是,比如一个我等3个小时,一个是我等到下午3点的…...

HCIA-HarmonyOS Application Developer——题目集1
题目1 1、一位开发人员在设计应用程序时,添加了一个Text组件和Button组件,开发样图如下所示。该开发者不能选择哪种布局方式来放置组件? A、StackLayout B、DependentLayout C、DirectionalLayout D、TableLayout 解析:(A&#…...

高性能 Message ToJavaBean 工具 【easy.server.mapper】
easy.server.mapper 介绍 后端开发中,消息转换常见问题 Map 中的数据 转换成实体Bean数组 中的数据 转换成实体BeanServet 中的 param 转换成实体Bean 以上的三个问题是最常见的消息转换困扰。 以Map 举例 常见做法是 手动转换 Map<String,Object> da…...

Web前端学习:三 - 练习
三六:风筝效果 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style type"text/css">*{margin: 0;padding: 0;}.d1{width: 200px;height: 200px;background: yellow;position…...

面试题:Android 中 Intent 采用了什么设计模式?
答案是采用了原型模式。原型模式的好处在于方便地拷贝某个实例的属性进行使用、又不会对原实例造成影响,其逻辑在于对 Cloneable 接口的实现。 话不多说看下 Intent 的关键源码: // frameworks/base/core/java/android/content/Intent.java public cla…...

Java数据类型与变量
个人主页:平行线也会相交 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【JavaSE_primary】 文章目录字面常量数据类型变量整型变量字节型变量浮点数变量双精度浮点数单精度浮点数字符型变量布尔型变量空常量nu…...

Python为CANoe工程添加/删除DBC文件
前面文章我们对于通过COM来实现打开CANoe、导入CANoe配置工程、导入执行文件、启动CANoe软件和执行脚本;但是这只能完成最基本的功能调用,在实际得到使用过程中,特别是各家在推的CI/CD以及平台化,仅仅是实现这些功能是完全不够用的;比如dbc的添加和删除,这是我们非常必要…...

不同的产品经理特征和需要的能力
产品经理是一个管家,需要和各方沟通推动产品各个决策进展。 每天早上看看线上用户数据、看下今天要安排任务,接着就是和各方开会讨论推动产品实现。每天穿插于与 UI、用户以及完成自己的 todolist 中循环。如果公司体制完善,还要和运营、数据…...

webpack之处理样式资源
处理样式资源 本章节我们学习使用 Webpack 如何处理 Css、Less、Sass、Scss、Styl 样式资源 #介绍 Webpack 本身是不能识别样式资源的,所以我们需要借助 Loader 来帮助 Webpack 解析样式资源 我们找 Loader 都应该去官方文档中找到对应的 Loader,然后…...

Golang 接口笔记
基本介绍接口是一个数据类型,可以定义一组方法,但都不需要实现。并且interface中不能包含任何变量。到某个自定义类型要使用的时候,再根据具体情况把这些方法实现出来语法type 接口名 interface {method1(参数列表) 返回值列表method2(参数列…...

[计算机网络(第八版)]第二章 物理层(章节测试/章节作业)
章节作业 带答案版 选择题 (单选题)双绞线是用两根绝缘导线绞合而成的,绞合的目的是( )。 A. 减少干扰 B. 提高传输速度 C. 增大传输距离 D. 增大抗拉强度(单选题)在电缆中采用屏蔽技术可以带来的好处主要是( )。 A…...

[iOS 理解] Swift Runtime (1) 类
Warm up 先看一段代码: import ObjectiveCclass Obj {var x: Double 0 }let v: NSObjectProtocol Obj() as! NSObjectProtocol let result v.isKind(of: Obj.self) let size class_getInstanceSize(Obj.self)我们有一个没有继承 NSObject、没有遵循 NSObjectP…...

ASEMI低压MOS管20N06参数,20N06体积,20N06大小
编辑-Z ASEMI低压MOS管20N06参数: 型号:20N06 漏极-源极电压(VDS):60V 栅源电压(VGS):20V 漏极电流(ID):20A 功耗(PD࿰…...

常见前端基础面试题(HTML,CSS,JS)(四)
作用域和作用域链的理解 作用域 (1)全局作用域 最外层函数和最外层函数外面定义的变量拥有全局作用域所有未定义直接赋值的变量自动声明为全局作用域所有window对象的属性拥有全局作用域全局作用域有很大的弊端,过多的全局作用域变量会污染…...

RabbitMQ发布确认模式
目录 一、发布确认原理 二、发布确认的策略 (一)开启发布确认的方法 (二)单个确认模式 (三)批量确认模式 (四)异步确认模式 (五)如何处理异步未确认消…...

零基础的人如何入门 Python ?看完这篇文章你就懂了
第一部分:编程环境准备 零基础入门Python的话我不建议用IDE,IDE叫集成开发环境,这东西一般是专业程序员用来实战开发用的,好处很多,比如:调试、语法高亮、项目管理、代码跳转、智能提示、自动完成、单元测…...

Atcoder abc257 E
E - Addition and Multiplication 2 题意: 给你一个数字n表示你现在拥有的金额 然后给你1~9每个经营额所需要的成本, 设总经营额为x, 当前使用的经营额为y, 则每一次使用经营额时都有x10*xy 问, 如何在使用不大于成本数量的金额下, 使得经营额最高 例如: 5 5 4 3 8 1 6 7 …...

模拟退火算法改进
import numpy as np import matplotlib.pyplot as plt import math import random from scipy.stats import norm from mpl_toolkits.mplot3d import Axes3D # 目标函数 def Function(x, y): return -20 * np.exp(-0.2*np.sqrt(0.5*(x*xy*y)))\ -np.exp(0.5*(n…...

SpringBoot+HttpClient+JsonPath提取A接口返回值作为参数调用B接口
前言 在做java接口自动化中,我们常常需要依赖多个接口,A接口依赖B,C,D接口的响应作为请求参数;或者URL中的参数是从其他接口中提取返回值作获取参数这是必不可少的。那么怎么实现呢?下面就来介绍多业务依赖…...

JUC 之 CompletableFuture
——CompletableFuture Future Future 接口(FutureTask 实现类) 定义了操作异步任务执行的一些方法,如获取异步的执行结果、取消任务的执行、判断任务是否被取消、判断任务执行是否完毕例如: 主线程让一个子线程去执行任务&…...

7-vue-1
谈谈你对MVVM的理解 为什么要有这些模式,目的:职责划分、分层(将Model层、View层进行分类)借鉴后端思想,对于前端而已,就是如何将数据同步到页面上 MVC模式 代表:Backbone underscore jquer…...

OpenAPI SDK组件介绍
背景 公司成立以来,积累了数以万计的可复用接口。上层的SaaS业务,原则上要复用这些接口开发自己的业务,为了屏蔽调用接口的复杂性,基础服务开发了apisdk组件,定义了一套声明OpenAPI的注解、注解解析器,实例…...

【Java】Synchronized锁原理和优化
一、synchronized介绍 synchronized中文意思是同步,也称之为”同步锁“。 synchronized的作用是保证在同一时刻, 被修饰的代码块或方法只会有一个线程执行,以达到保证并发安全的效果。 synchronized是Java中解决并发问题的一种最常用的方法…...

西北工业大学2020-2021学年大物(I)下期末试题选填解析
2 位移电流。磁效应服从安培环路,热效应不服从焦耳-楞次定律。注意,它是变化的电场而非磁场产生。3 又考恒定磁场中安培环路定理。4感生电场5 麦克斯韦速率分布函数。6 相同的高温热源和低温热源之间的一切可逆热机的工作效率相等,无论工质如…...