进程相关内容描述

01. 并行和并发(理解)

并行(parallel):指在同一时刻,有多条指令在多个处理器上同时执行。

并发(concurrency):指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行。

举例说明:

  • 并行是两个队列同时使用两台咖啡机
  • 并发是两个队列交替使用一台咖啡机

02. MMU

​ MMU是Memory Management Unit的缩写,中文名是内存管理单元,它是中央处理器(CPU)中用来管理虚拟存储器、物理存储器的控制线路,同时也负责虚拟地址映射为物理地址,以及提供硬件机制的内存访问授权,多用户多进程操作系统。

06. 进程控制块PCB

​ 进程运行时,内核为进程每个进程分配一个PCB(进程控制块),维护进程相关的信息,Linux内核的进程控制块是task_struct结构体。

在 /usr/src/linux-headers-xxx/include/linux/sched.h 文件中可以查看struct task_struct 结构体定义:

其内部成员有很多,我们掌握以下部分即可:

  • 进程id。系统中每个进程有唯一的id,在C语言中用pid_t类型表示,其实就是一个非负整数。
  • 进程的状态,有就绪、运行、挂起、停止等状态。
  • 进程切换时需要保存和恢复的一些CPU寄存器。
  • 描述虚拟地址空间的信息。
  • 描述控制终端的信息。
  • 当前工作目录(Current Working Directory)。
  • umask掩码。
  • 文件描述符表,包含很多指向file结构体的指针。
  • 和信号相关的信息。
  • 用户id和组id。
  • 会话(Session)和进程组。
  • 进程可以使用的资源上限(Resource Limit)。

03. 进程的状态

进程状态反映进程执行过程的变化。这些状态随着进程的执行和外界条件的变化而转换。

在三态模型中,进程状态分为三个基本状态,即运行态,就绪态,阻塞态

在五态模型中,进程分为新建态、终止态,运行态,就绪态,阻塞态

​ ①TASK_RUNNING:进程正在被CPU执行。当一个进程刚被创建时会处于TASK_RUNNABLE,表示己经准备就绪,正等待被调度。

②TASK_INTERRUPTIBLE(可中断):进程正在睡眠(也就是说它被阻塞)等待某些条件的达成。一旦这些条件达成,内核就会把进程状态设置为运行。处于此状态的进程也会因为接收到信号而提前被唤醒比如给一个TASK_INTERRUPTIBLE状态的进程发送SIGKILL信号,这个进程将先被唤醒(进入TASK_RUNNABLE状态),然后再响应SIGKILL信号而退出(变为TASK_ZOMBIE状态),并不会从TASK_INTERRUPTIBLE状态直接退出。

③TASK_UNINTERRUPTIBLE(不可中断):处于等待中的进程,待资源满足时被唤醒,但不可以由其它进程通过信号或中断唤醒。由于不接受外来的任何信号,因此无法用kill杀掉这些处于该状态的进程。而TASK_UNINTERRUPTIBLE状态存在的意义就在于内核的某些处理流程是不能被打断的。如果响应异步信号,程序的执行流程中就会被插入一段用于处理异步信号的流程,于是原有的流程就被中断了,这可能使某些设备陷入不可控的状态。处于TASK_UNINTERRUPTIBLE状态一般总是非常短暂的,通过ps命令基本上不可能捕捉到。

④TASK_ZOMBIE(僵死):表示进程已经结束了,但是其父进程还没有调用wait4或waitpid()来释放进程描述符。为了父进程能够获知它的消息,子进程的进程描述符仍然被保留着。一旦父进程调用了wait4(),进程描述符就会被释放。

⑤TASK_STOPPED(停止):进程停止执行。当进程接收到SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU等信号的时候。此外,在调试期间接收到任何信号,都会使进程进入这种状态。当接收到SIGCONT信号,会重新回到TASK_RUNNABLE

使用ps aux可查看stat状态

stat中的参数意义如下:

参数含义
D不可中断 Uninterruptible(usually IO)
R正在运行,或在队列中的进程
S(大写)处于休眠状态
T停止或被追踪
Z僵尸进程
W进入内存交换(从内核2.6开始无效)
X死掉的进程
<高优先级
N低优先级
s包含子进程
+位于前台的进程组

7.1 ps

进程是一个具有一定独立功能的程序,它是操作系统动态执行的基本单元。

ps命令可以查看进程的详细状况,常用选项(选项可以不加“-”)如下:

选项含义
-a显示终端上的所有进程,包括其他用户的进程
-u显示进程的详细状态
-x显示没有控制终端的进程
-w显示加宽,以便显示更多的信息
-r只显示正在运行的进程

ps aux

ps ef

ps -a

top

top命令用来动态显示运行中的进程。top命令能够在运行后,在指定的时间间隔更新显示信息。可以在使用top命令时加上-d 来指定显示信息更新的时间间隔。

在top命令执行后,可以按下按键得到对显示的结果进行排序:

按键含义
M根据内存使用量来排序
P根据CPU占有率来排序
T根据进程运行时间的长短来排序
U可以根据后面输入的用户名来筛选进程
K可以根据后面输入的PID来杀死进程。
q退出
h获得帮助

20.3 kill

kill命令指定进程号的进程,需要配合 ps 使用。

使用格式:

kill [-signal] pid

信号值从0到15,其中9为绝对终止,可以处理一般信号无法终止的进程。

kill 9133 :9133 为应用程序所对应的进程号

有些进程不能直接杀死,这时候我们需要加一个参数“ -9 ”,“ -9 ” 代表强制结束:

20.4 killall

通过进程名字杀死进程

kill [-signal] pname(进程名字)

08. 进程号和相关函数

每个进程都由一个进程号来标识,其类型为 pid_t(整型),进程号的范围:0~32767。进程号总是唯一的,但进程号可以重用。当一个进程终止后,其进程号就可以再次使用。

接下来,再给大家介绍三个不同的进程号。

进程号(PID)

​ 标识进程的一个非负整型数。

父进程号(PPID)

​ 任何进程( 除 init 进程)都是由另一个进程创建,该进程称为被创建进程的父进程,对应的进程号称为父进程号(PPID)。如,A 进程创建了 B 进程,A 的进程号就是 B 进程的父进程号。

进程组号(PGID)

​ 进程组是一个或多个进程的集合。他们之间相互关联,进程组可以接收同一终端的各种信号,关联的进程有一个进程组号(PGID) 。这个过程有点类似于 QQ 群,组相当于 QQ 群,各个进程相当于各个好友,把各个好友都拉入这个 QQ 群里,主要是方便管理,特别是通知某些事时,只要在群里吼一声,所有人都收到,简单粗暴。但是,这个进程组号和 QQ 群号是有点区别的,默认的情况下,当前的进程号会当做当前的进程组号。

8.1 getpid函数

#include <sys/types.h>
#include <unistd.h>

pid_t getpid(void);
功能:
	获取本进程号(PID)
参数:
	无
返回值:
	本进程号

8.2 getppid函数

#include <sys/types.h>
#include <unistd.h>

pid_t getppid(void);
功能:
	获取调用此函数的进程的父进程号(PPID)
参数:
	无
返回值:
	调用此函数的进程的父进程号(PPID)

8.3 getpgid函数

#include <sys/types.h>
#include <unistd.h>

pid_t getpgid(pid_t pid);
功能:
	获取进程组号(PGID)
参数:
	pid:进程号
返回值:
	参数为 0 时返回当前进程组号,否则返回参数指定的进程的进程组号

示例程序:

int main()
{
	pid_t pid, ppid, pgid;

	pid = getpid();
	printf("pid = %d\n", pid);

	ppid = getppid();
	printf("ppid = %d\n", ppid);

	pgid = getpgid(pid);
	printf("pgid = %d\n", pgid);

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值