【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 执行可执行程序
![](/assets/blank.gif)
发现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】孤儿进程 | 环境变量 | 命令行参数 | 进程优先级相关推荐
- 进程环境之命令行参数
当执行一个程序时,调用exec的进程可将命令行参数传递给该新进程.这是UNIX shell的一部分常规操作. 程序清单7-3 将所有命令行参数回送到标准输出 [root@localhost apue] ...
- Qt通过QProcess启动进程并传递命令行参数
目录 QProcess 启动外部程序的两种方式 依赖式 分离式: 启动进程前的预处理 设置启动路径 设置启动命令参数 启动的状态 更多说明 Public Functions Signals 设计一个拉 ...
- linux命令行如何上翻,Linux学习教程-获取可用命令行参数 or 文件上下翻转和左右翻转...
导读 前面使用的,有几个用到了参数如ls -l, head -n 6等,需要注意的是跟参数之间要有空格. 获取可用命令行参数 终端运行man ls可以查看ls所有可用的参数,上下箭头翻页,按q退出查看 ...
- linux shell 特殊变量 符号 $0, $#, $*, $@, $?, $$ 命令行参数
特殊变量列表 变量 含义 $0 当前脚本的文件名 $n 传递给脚本或函数的参数.n 是一个数字,表示第几个参数.例如,第一个参数是$1,第二个参数是$2. $# 传递给脚本或函数的参数个数. $* 传 ...
- linux读取命令行参数,Linux学习笔记(五)—— Linux命令行参数
一.客户端输入 脚本执行的过程是对数据变量进行处理的过程,之前在脚本中处理的数据都是静态数据,而不是和客户端交互的动态数据.在大多数情况下脚本执行过程需要和客户端进行交互,用来获得脚本处理的数据,这些 ...
- linux 中解析命令行参数 (getopt_long用法)
getopt_long支持长选项的命令行解析,使用man getopt_long,得到其声明如下: #include <getopt.h> int getopt_long ...
- Shell特殊变量:Shell $0, $#, $*, $@, $?, $$和命令行参数
前面已经讲到,变量名只能包含数字.字母和下划线,因为某些包含其他字符的变量有特殊含义,这样的变量被称为特殊变量. 例如,$ 表示当前Shell进程的ID,即pid,看下面的代码: $echo $$ 运 ...
- Shell特殊变量:Shell $0,$#,$*,$@,$?,$$和命令行参数
特殊变量列表 变量 含义 $0 当前脚本的文件名 $n 传递给脚本或函数的参数.n是一个数字,表示第几个参数.例如,第一个参数是$1,第二个参数是$2. $# 传递给脚本或函数的参数个数 $* 传递给 ...
- linux的memmap函数_究竟有多少linux内核命令行参数
linux启动时可以带命令行参数,这些参数会影响内核乃至启动脚本的行为.在内核中,用early_param(命令行参数名称,命令行参数处理函数)来注册.除了内核参数,还可以有其他的命令行参数,各自有自 ...
最新文章
- RHEL 5服务篇—修改MySQl数据库root密码的几种方式
- python3环境下“No module named nibabel”的解决办法
- Linux下不同服务器间数据传输
- axure9 html文件使用ie打开图片无法显示_win7系统html文件如何打开 win7系统html文件打开方法【介绍】...
- 一次mysql大数据量查询 慢查询导致服务阻塞后的学习
- double类型问题
- Iframe的那些事
- 在Windows 7或Vista(或Windows 8.x,Sorta)上禁用Aero
- 二次元风格Kratos-pjax主题 WordPress主题
- MFC - CStdioFile 读取txt文件UNICODE 中文异常
- Linux手机研发要过五大难关
- Java数据库编程---JDBC操作步骤及数据库连接操作
- 高等数学导数公式、微分公式和积分公式大全
- IntelliJ IDEA导包快捷键
- Slate轨道工具使用(四)—根动画与位置
- 如何使用餐饮互动游戏进行拓客?餐饮加盟h5线下互动游戏能收获什么?
- 我的专业偶像作文计算机,我的崇拜的偶像作文(通用5篇)
- 简单实现PDF转换为WORD,去水印
- 解决:cannot import name ‘xxx‘ from ‘xxx‘
- 十进制转二进制函数实现(C语言)