1.PCB
Linux系统中使用进程控制块PCB来描述进程,它实际上是一个名为task_struct的结构体
task_ struct内容分类 :
-
标示符: 描述本进程的唯一标示符,用来区别其他进程。
状态: 任务状态,退出代码,退出信号等。
优先级: 相对于其他进程的优先级。
程序计数器: 程序中即将被执行的下一条指令的地址。
内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
其他信息
-
2.查看进程方法
- (1)查看系统文件/proc的方法:
- (2)通过ps指令:
-
ps命令是Linux下的一个进程查看命令,用于显示当前进程的状态。下面是ps命令的各个参数:
- -a:显示所有进程。
- -u:以用户为主的格式来显示进程。
- -x:显示没有控制终端的进程。
- -e:显示所有进程,与-a参数相同。
- -f:显示详细的进程信息。
- -l:显示长格式的进程信息。
- -o:自定义输出格式。
- -j:显示作业控制信息,包括进程ID、会话ID、进程组ID、终端等信息。
常用方法是ps axj | head -1 && ps axj | grep xxxx
例如:
(3)通过系统调用
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
printf("pid: %d\n", getpid());//输出本进程id
printf("ppid: %d\n", getppid());//输出父进程id
return 0;
}
2.创建子进程
fork函数是Linux下的一个系统调用,用于创建一个新进程。该函数会复制当前进程的所有信息,包括代码段、数据段、堆、栈等,然后将其作为新进程的信息。新进程与原进程几乎完全相同,但是它们有不同的进程ID。下面是fork函数的一些详细介绍:
- fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程。
- 两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。
- fork()函数返回两次,一次在父进程中返回子进程ID,另一次在子进程中返回0,可以通过此用if判断在父进程中还是子进程中。
- 如果出现错误,fork()函数返回一个负值。
经典场景:
注意:"[test1@iZ0jl0mqkm4w1kxah243kiZ review]$ 被32677所调用"是一个巧合, 恰号证明了进程的切换, 在fork函数没有执行完时, bash子进程命令行却输出了自己的提示符。
3.进程状态
(1)Linux内核中对状态的定义:
R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列
里。
S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠
(interruptible sleep))
D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的 进程通常会等待IO的结束。
T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可 以通过发送 SIGCONT 信号让进程继续运行。
X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态
(2)僵尸进程和孤儿进程
僵尸进程(Zombie Process):
僵尸进程是已经终止(退出)的子进程,但其父进程还未来得及获取子进程的终止状态信息。当一个进程终止时,内核会将一些进程资源保留,以便父进程可以获取有关子进程终止的信息,这包括退出状态和一些其他元数据。如果父进程没有显式地等待子进程的终止状态,那么子进程就会成为僵尸进程。
僵尸进程已经释放了进程运行时所占用的系统资源(不包括PCB块),但如果产生大量僵尸进程,可能会耗尽进程表空间。避免僵尸进程的一种方法是父进程通过wait()
或waitpid()
等系统调用来等待子进程的终止状态,然后释放子进程的资源。另一种方法是使用信号处理程序来捕获SIGCHLD
信号,以处理子进程终止状态。
孤儿进程(Orphan Process):
孤儿进程是指其父进程终止或非正常终止后仍在运行的进程。在这种情况下,孤儿进程的父进程将由init
进程(进程ID为1)接管。init
进程会周期性地等待任何孤儿进程的终止状态,确保孤儿进程的资源被正确释放。
孤儿进程的出现通常是因为父进程在子进程创建后终止,但子进程继续运行。由于init
进程会承担孤儿进程的监管责任,孤儿进程并不会一直存在,因为一旦它们终止,它们的资源将被释放。
总结:
- 僵尸进程是指已经终止的子进程,但其终止状态还未被父进程获取的情况。
- 孤儿进程是指父进程已经终止或非正常终止,而子进程继续运行的情况。
- 为避免僵尸进程,父进程应该适时获取子进程的终止状态。
- 孤儿进程会被
init
进程接管,并在终止后其资源被释放。