目录
一.进程概念与子进程
1.进程基本概念
2.通过系统调用创建子进程-fork
二.进程状态
1、一般进程状态
2、Linux操作系统的进程状态
三.环境变量
1.概念
2.环境变量组织与获取
3.配置文件
4.环境变量的全局属性编辑
5.命令行参数
四.进程优先级
1.查看系统进程
2.其他概念
一.进程概念与子进程
1.进程基本概念
程序的一个执行实例,正在执行的程序等
担当分配系统资源(CPU时间,内存)的实体。
描述进程-PCB
进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。
一般称之为PCB(process control block), Linux操作系统下的PCB叫: task_struct。task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。
task_ struct内容分类:
标示符: 描述本进程的唯一标示符,用来区别其他进程。
状态: 任务状态,退出代码,退出信号等。
优先级: 相对于其他进程的优先级。
程序计数器: 程序中即将被执行的下一条指令的地址。
内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
I/ O状态信息: 包括显示的I/O请求,分配给进程的I/ O设备和被进程使用的文件列表。
记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
其他信息
进程组织:
可以在内核源代码里找到它。所有运行在系统里的进程都以task_struct链表的形式存在内核里。
查看进程:
进程的信息可以通过 /proc 系统文件夹查看
如:要获取PID为1的进程信息,你需要查看 /proc/1 这个文件夹
2.通过系统调用创建子进程-fork
fork有两个返回值
父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝)
#include<iostream>
2 #include<unistd.h>
3 using namespace std;
4 int main()
5 {
6 pid_t id=fork();
7 if(id==0)
8 {
9 //父进程
10 cout<<"I am parent ! my pid :"<<getpid()<<" my parent process id:"<<getppid()<<endl;
11 }
12 else if(id>0)
13 {
14 //子进程
15 cout<<"I am child ! my pid :"<<getpid()<<" my parent process id:"<<getppid()<<endl;
16 }
17 else
18 {
19 //error
20 }
21 }
- pid_t fork(void);//在父进程中,fork返回新创建子进程的进程ID;在子进程中,fork返回0;如果出现错误,fork返回一个负值;
- pid_t getpid(); // 获取当前进程的 pid 值。
- pid_t getppid(); //获取当前进程的父进程 pid 值。
二.进程状态
1、一般进程状态
阻塞:进程因为等待某种条件就绪,而导致的一种不推进的状态。阻塞一定是在等待某种资源如键盘、网卡、磁盘、显卡等,通过等待的方式,等具体的资源被别的进程使用完成之后,再被自己使用。
阻塞挂起:当内存中进程过多而导致内存空间不足时,操作系统会根据对应的算法将闲置的暂时不用的进程对应的代码和数据交换到磁盘里。
2、Linux操作系统的进程状态
/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
R运行状态(running) : 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在cpu运行队列里。即包括一般进程状态分类里的就绪和执行。
使用 ps axj命令查看进程的状态:
ps axj | head -1 && ps axj | grep prostatus
S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠
(interruptible sleep),意味着可以被暂停和中断)。
D磁盘休眠状态(Disk sleep):有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。处于该状态的进程不可以被强制杀死。一般程序员难以遇到这种情况。
T停止状态(stopped): 进程收到操作系统或者用户的暂停命令而停下。可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。可以使用命令:kill -l 查看相关信号
t追踪状态(tracing stop):一般来说,调试程序时遇到断点儿停下时,该进程就处于t状态。
X死亡状态(dead):进程终止的一瞬间。这个状态只是一个返回状态,在任务列表里看不到。
Z僵死状态(Zombies):是一个比较特殊的状态。当进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵死(尸)进程。僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态。
僵尸进程危害:
父进程如果一直不读取子进程的退出结果和退出码,那子进程就一直处于Z状态,系统需要维护退出状态,所以子进程还会保存在task_struct(PCB)中。所以僵尸进程一直不处理会造成内存泄露。
补充:+号,加号代表的是后台运行的进程,无法按ctrl+c键终止进程,可以通过命令:kill -9加进程id 或者killall +进程名杀除对应进程。不带加号的为前台运行进程,按ctrl+c键可以终止进程。
孤儿进程:父进程先退出,子进程就称之为“孤儿进程”,,但是孤儿进程会被1号init进程领养,init进程会进行回收。
守护进程&精灵进程:这两种是同一种进程的不同翻译,是特殊的孤儿进程,不但运行在后台,最主要的是脱离了与终端和登录会话的所有联系,也就是默默的运行在后台不想受到任何影响。运行在后台,独立于控制终端并周期性地执行某些任务。
三.环境变量
1.概念
环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。
查看环境变量:
env 查看所有环境变量名称和内容 等号前为环境名称,等号后为变量的具体内容
echo $环境变量 查看该变量名称的具体内容
常见环境变量:
HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
SHELL : 当前Shell,它的值通常是/bin/bash
PATH : 指定命令的搜索路径
我们写的程序必须带上具体的路径让shell能找到我们的程序在哪里,如果不具体指明的话shell找不到执行程序。然而,系统指令却可以不带路径,直接运行,是因为shell会去环境变量PATH里的路径里找,而且系统指令的执行程序的所在路径就在PATH里。
which +命令 查看命令所在路径。
设置环境变量
export: 设置一个新的环境变量
unset: 清除环境变量
set: 显示本地定义的shell变量和环境变量
export设置PATH:export PATH=$PATH:要增加的路径名
2.环境变量组织与获取
环境变量的组织方式
环境变量本质就是一个内存级的一张表,这张表由用户在登陆系统时时候,进行给特定用户形成属于自己的环境变量表。环境变量中的每一个,都有自己的用途:有的是进行路径查找的,有的进行身份认证的,有的时进行动态库查找的,有的是用来进行确认当前路径的……每一个环境变量都有自己的特定应用场景。一般这张表都是开机时,系统从相关配置文件中读取进来的!
环境表本质是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串
通过代码如何获取环境变量
1.命令行第三个参数
2.通过第三方变量environ获取
3.通过系统调用获取或设置环境变量:
putenv , 用于改变或增加环境变量的内容
getenv ,搜索 指定字符串所指向的环境字符串,并返回相关的值给字符串。
3.配置文件
使用shell时,默认环境变量存放在~/.bash_profile文件里。
- ~/.bash_profile:用户级的环境配置文件,每个用户目录下都会具有各自的,在用户每次登录系统时被读取,里面所有命令都会被shell执行。包括环境变量的配置命令,因此A正确
- /etc/progile.d :一个目录,其中包含了系统级的环境配置文件,任意用户登录时都会执行这个目录下的环境配置文件完成环境配置,但是要注意这个是目录并不是保存环境变量配置的配置文件
- 使用以下两个命令
. source
加上配置文件,使得该文件立马生效。
4.环境变量的全局属性
子进程默认会复制拥有与父进程相同的环境变量,因为bash创建子进程时会通过参数传递将环境变量表传给子进程。因为环境变量是可以被相关的子进程继承下去的,环境变量具有全局属性。
一般在shell命令行直接创建的变量只存储与shell局部,不具有全局属性,叫做本地变量。因为存储位置不同 ,本地变量不会传递给子进程。
5.命令行参数
执行程序时,可以从命令行传值给程序。这些值被称为命令行参数。命令行参数是使用 main() 函数参数来处理的,其中,argc 是指传入参数的个数,argv[] 是一个指针数组,指向命令行传递给程序的每个参数,以空格为分隔符。
应用:实现程序根据输入参数进行不同处理。
四.进程优先级
cpu资源分配的先后顺序,就是指进程的优先权(priority)。优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。还可以把进程运行到指定的CPU上,把不重要的进程安排到某个CPU,可以大大改善系统整体性能。
1.查看系统进程
在linux或者unix系统中,使用命令:
ps –l
表头的几个重要信息如下:
UID : 代表执行者的身份
PID : 代表这个进程的代号
PPID :代表这个进程是由哪个进程发展衍生而来的,即父进程的代号
PRI :代表这个进程可被执行的优先级,其值越小越早被执行
NI :代表这个进程的nice值
详解NI:
PRI,priority,进程的优先级,即程序被CPU执行的先后顺序,此值越小进程的优先级别越高。NI,nice值表示进程可被执行的优先级的修正数值。加入nice值后,PRI会变为:
PRI(new)=PRI(固定值80)+nice
想要调整进程优先级,在Linux下,就是调整进程nice值
nice其取值范围是-20至19,一共40个级别。进程的nice值不是进程的优先级,但是进程nice值会影响到进程的优先级变化。可以理解nice值是进程优先级的修正修正数据
用top命令更改已存在进程的nice:
1、top
2、进入top后按“r”–>输入进程PID–>输入nice值
2.其他概念
竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰
并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行
并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发