如何给企业做网站,seo顾问阿亮,邢台手机网站建设信息,网站备案与icp备案目录
Linux源代码对进程的描述
R
S
D
T
t
X
Z#xff08;进程僵尸#xff09;
孤儿进程 Linux源代码对进程的描述 理论上把进程状态大致被分为了#xff1a;运行、阻塞、挂起。那么#xff0c;在操作系统中具体是如何描述状态的。#xff08;有时候Linux内核也把…目录
Linux源代码对进程的描述
R
S
D
T
t
X
Z进程僵尸
孤儿进程 Linux源代码对进程的描述 理论上把进程状态大致被分为了运行、阻塞、挂起。那么在操作系统中具体是如何描述状态的。有时候Linux内核也把进程称为任务 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 Rrunning运行状态并不意味着进程一定正在被CPU执行只要进程在运行队列中都显示为运行状态。对应理论中的运行状态
S Ssleeping睡眠状态意味着进程正在等待硬件或者软件资源用S表示的睡眠状态是可中断睡眠也称为浅度睡眠。对应理论中的阻塞状态 在目录24919下面编辑文件myprocess.c的内容如下。
[eutoVM-4-13-centos 24919]$ cat myprocess.c
#include stdio.h
#include unistd.h
#include sys/types.h
#include stdlib.hint main()
{ while(1){printf(I am a process\n);sleep(1);}return 0;
}程序运行起来后不要中断运行。
[eutoVM-4-13-centos 24919]$ ./myprocess
I am a process
I am a process
I am a process
I am a process
······· 在新的窗口打印进程信息。
[eutoVM-4-13-centos 24919]$ ps ajx | head -1 ps ajx | grep myprocessPPID PID PGID SID TTY TPGID STAT UID TIME COMMAND4223 7525 7525 4223 pts/2 7525 S 1001 0:00 ./myprocess7157 7564 7563 7157 pts/3 7563 R 1001 0:00 grep --colorauto myprocess其中STAT这一列用来表示运行状态。
程序myprocess正在被执行打印的进程状态应该是R为什么是S 其实这和程序的功能有关我所写的这个源文件只有一行printf当程序运行起来后执行printf这一行代码的速度是非常非常快的而这一行代码的执行结果是要把字符串输出到显示器显示器属于硬件资源其实这个程序的99%的时间都用来将字符串输出到显示器这个进程大部分时间都是在阻塞队列中排队因此进程状态是S。如果有幸在打印的瞬间进程正在运行队列中排队那么打印的结果就会是R。 实际上大部分进程都会和外设产生关联因此大部分进程都处在S状态而非R状态。
为什么grep的进程状态是R grep用来全局搜索那么只有当grep处于运行状态R时才能做正在搜索的动作。
S中的是什么意思 我们在命令行中运行程序后所启动的程序可以称为前台程序前台程序启动后在命令行执行其他指令是没有响应的使用Ctrl C可以中断运行如果是前台程序则进程状态都会有的字样。
[eutoVM-4-13-centos 24919]$ ./myprocess
I am a process
I am a process
I am a process
I am a process
I am a process
I am a process
pwdI am a process//运行pwd是没有响应的I am a process
I am a process
I am a process
cdI am a process//运行cd是没有响应的.I am a process
^HcI am a process
^H^HI am a process
cd ..I am a processI am a process
^C//CtrlC是可以中断执行流的如果执行下面这条指令来运行可执行程序则启动的程序称为后台程序后台程序运行的时候如果在命令行中执行其他指令是可以被响应的。但是执行Ctrl C不能中断运行后台程序。后台进程的进程状态不带字样。
[eutoVM-4-13-centos 24919]$ ./myprocess
[1] 7297
[eutoVM-4-13-centos 24919]$ I am a process
I am a process
pwd//pwd被响应
/home/euto/linux/24919
[eutoVM-4-13-centos 24919]$ I am a process
lsI am a processMakefile myprocess myprocess.c
[eutoVM-4-13-centos 24919]$ llI am a process
//ll被响应
total 20
-rw-rw-r-- 1 euto euto 82 Sep 19 17:56 Makefile
-rwxrwxr-x 1 euto euto 8416 Sep 19 19:47 myprocess
-rw-rw-r-- 1 euto euto 173 Sep 19 19:46 myprocess.c
[eutoVM-4-13-centos 24919]$ I am a process
I am a process
^C//Ctrl C不能中断运行
[eutoVM-4-13-centos 24919]$ I am a process
I am a process进程状态不带字样。
[eutoVM-4-13-centos 24921]$ ps ajx | head -1 ps ajx | grep myprocessPPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
31606 824 824 31606 pts/1 31606 S 1001 0:00 ./myprocess476 861 860 476 pts/2 860 S 1001 0:00 grep --colorauto myprocess如果要中断运行则执行kill指令杀掉进程。
[eutoVM-4-13-centos 24919]$ kill -l1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN1 36) SIGRTMIN2 37) SIGRTMIN3
38) SIGRTMIN4 39) SIGRTMIN5 40) SIGRTMIN6 41) SIGRTMIN7 42) SIGRTMIN8
43) SIGRTMIN9 44) SIGRTMIN10 45) SIGRTMIN11 46) SIGRTMIN12 47) SIGRTMIN13
48) SIGRTMIN14 49) SIGRTMIN15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX 信号9的功能是杀掉进程后面跟上进程的PID。
[eutoVM-4-13-centos 24919]$ ps ajx | head -1 ps ajx | grep myprocessPPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
13708 7297 7297 13708 pts/2 13708 S 1001 0:00 ./myprocess
13887 7493 7492 13887 pts/3 7492 S 1001 0:00 grep --colorauto myprocess
[eutoVM-4-13-centos 24919]$ kill -9 7297//杀掉进程
·········
I am a process[1] Killed ./myprocessD Ddisk sleeping磁盘睡眠状态只不过这种睡眠状态是不可中断睡眠也称为深度睡眠。D状态也对应理论中的阻塞状态。 一般如果一个进程在等待磁盘的资源那么这个进程的状态大概率会被设置为D。在内存资源紧张的时候这个时候操作系统要选择释放掉部分进程而状态为D的进程操作系统会保留。 一般如果出现D状态的进程说明操作系统访问磁盘的速度已经非常慢了系统离奔溃也不远了。
T Tstopped暂停状态如果一个进程想要获取某种硬件或者软件资源但是当前资源并不能让进程获取到比如不允许进程访问显示器资源而操作系统也不想杀掉这个进程为了防止这个进程有非法操作故将这个进程状态设置为T。T也对应理论中的阻塞状态 通过kill命令发送19号信号可以让进程处于暂停的状态同时也变成了后台进程。可以发送18号信号让进程继续运行。
18) SIGCONT 19) SIGSTOP
[eutoVM-4-13-centos 24921]$ kill -19 12235
[eutoVM-4-13-centos 24921]$ ps ajx | head -1 ps ajx | grep myprocessPPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
31606 12235 12235 31606 pts/1 31606 T 1001 0:00 ./myprocess476 12402 12401 476 pts/2 12401 S 1001 0:00 grep --colorauto myprocesst ttracing stop被追踪的暂停状态。一般在调试程序中程序在断点处暂停的时候就是被gdb程序追踪的暂停状态。t也对应理论中的阻塞状态 启动调试程序后在第10行打一个断点。
(gdb) l 0
1 #include stdio.h
2 #include unistd.h
3 #include sys/types.h
4 #include stdlib.h
5
6 int main()
7 {
8 while(1)
9 {
10 printf(I am a process\n);
(gdb) b 10
Breakpoint 1 at 0x400581: file myprocess.c, line 10.
(gdb) r
Starting program: /home/euto/linux/24921/myprocess Breakpoint 1, main () at myprocess.c:10
10 printf(I am a process\n);
Missing separate debuginfos, use: debuginfo-install glibc-2.17-326.el7_9.x86_64
(gdb)
······ 此时查看进程状态就是t状态。
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
31606 25839 25839 31606 pts/1 25839 S 1001 0:00 gdb myprocess
25839 25940 25940 31606 pts/1 25839 t 1001 0:00 /home/euto/linux/24921/myprocess476 26437 26436 476 pts/2 26436 S 1001 0:00 grep --colorauto myprocessX XdeadX就是理论中的终止状态、进程死亡后的状态X一般是瞬时状态没法打印出来。对应理论中的死亡或者终止状态。
Z进程僵尸 Zzombie僵尸状态。 当一个进程准备死亡之前进程 PCB可执行程序操作系统会把代码和数据释放掉但是PCB会保留一段时间在这段时间内进程就是处于Z状态。 注意处于Z状态的时候进程已经退出了只是PCB被保留一段时间。 进程消亡的时候都要先后经过Z、X两种状态。
那么为什么操作系统要把一个消亡进程的PCB保留一段时间 进程都有父进程子进程都是由父进程创建出来的。父进程创建子进程的目的必然是为了完成某一个任务达到某种需求那么当这个进程快要消亡的时候这个进程所肩负的任务是否完成以及具体详情是怎么样的都要由父进程调用子进程的PCB才能得知故保留子进程的PCB一段时间来让父进程获取信息。 如果父进程没有调用消亡子进程的PCB会怎样 操作系统会把这个PCB一直保留这也算作内存泄露 编辑源文件的内容如下。
int main()
{pid_t id fork();if(id 0){int cnt 5;while(cnt){printf(I am child,pid:%d,ppid:%d\n,getpid(),getppid());sleep(1);--cnt;}exit(0);}//父进程while(1){printf(I am father,pid:%d,ppid:%d\n,getpid(),getppid());sleep(1);}return 0;
} 这个程序在运行五秒后子进程退出由于父进程没有读取PCB故子进程会处于僵尸状态。 PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
31606 10767 10767 31606 pts/1 10767 S 1001 0:00 ./myprocess
10767 10768 10767 31606 pts/1 10767 S 1001 0:00 ./myprocessPPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
31606 10767 10767 31606 pts/1 10767 S 1001 0:00 ./myprocess
10767 10768 10767 31606 pts/1 10767 S 1001 0:00 ./myprocess
······
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
31606 10767 10767 31606 pts/1 10767 S 1001 0:00 ./myprocess
10767 10768 10767 31606 pts/1 10767 Z 1001 0:00 [myprocess] defunctPPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
31606 10767 10767 31606 pts/1 10767 S 1001 0:00 ./myprocess
10767 10768 10767 31606 pts/1 10767 Z 1001 0:00 [myprocess] defunctPPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
31606 10767 10767 31606 pts/1 10767 S 1001 0:00 ./myprocess
10767 10768 10767 31606 pts/1 10767 Z 1001 0:00 [myprocess] defunct
······ 让父进程获取子进程的PCB信息后那么子进程的僵尸状态就会消失变成X状态只是X状态是瞬时状态显示器速度太慢我们打印不出来。 编辑源文件内容如下子进程变成僵尸后要让父进程作等待操作wait。
man 2 wait
WAIT(2) Linux Programmers Manual WAIT(2)NAMEwait, waitpid, waitid - wait for process to change stateSYNOPSIS#include sys/types.h#include sys/wait.hpid_t wait(int *status);pid_t waitpid(pid_t pid, int *status, int options);int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
······· 父子进程一起运行5s后。子进程变僵尸状态父进程继续运行5s。然后父进程等待僵尸状态消失。父进程再运行5s后程序结束运行。
int main()
{pid_t id fork();if(id 0){int cnt 5;while(cnt){printf(I am child,pid:%d,ppid:%d\n,getpid(),getppid());sleep(1);--cnt;}exit(0);}//父进程int cnt 10;while(cnt){printf(I am father,pid:%d,ppid:%d\n,getpid(),getppid());sleep(1);--cnt;}wait(NULL);printf(father get child\n);sleep(5);return 0;
}运行结果符合预期。 PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
31606 19361 19361 31606 pts/1 19361 S 1001 0:00 ./myprocess
19361 19362 19361 31606 pts/1 19361 S 1001 0:00 ./myprocessPPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
31606 19361 19361 31606 pts/1 19361 S 1001 0:00 ./myprocess
19361 19362 19361 31606 pts/1 19361 S 1001 0:00 ./myprocess
·······PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
31606 19361 19361 31606 pts/1 19361 S 1001 0:00 ./myprocess
19361 19362 19361 31606 pts/1 19361 Z 1001 0:00 [myprocess] defunctPPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
31606 19361 19361 31606 pts/1 19361 S 1001 0:00 ./myprocess
19361 19362 19361 31606 pts/1 19361 Z 1001 0:00 [myprocess] defunct
······PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
31606 19361 19361 31606 pts/1 19361 S 1001 0:00 ./myprocessPPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
31606 19361 19361 31606 pts/1 19361 S 1001 0:00 ./myprocess
·······孤儿进程 如果父子进程中父进程先退出子进程会发生什么变化。 编辑源文件内容如下让子进程运行50秒让父进程运行5s则父进程会先退出。
int main()
{pid_t id fork();if(id 0){int cnt 50;while(cnt){printf(I am child,pid:%d,ppid:%d\n,getpid(),getppid());sleep(1);--cnt;}exit(0);}//父进程int cnt 5;while(cnt){printf(I am father,pid:%d,ppid:%d\n,getpid(),getppid());sleep(1);--cnt;}运行结果如下。
[eutoVM-4-13-centos 24921]$ ./myprocess
I am father,pid:31424,ppid:31606
I am child,pid:31425,ppid:31424
I am father,pid:31424,ppid:31606
I am child,pid:31425,ppid:31424
I am father,pid:31424,ppid:31606
I am child,pid:31425,ppid:31424
I am father,pid:31424,ppid:31606
I am child,pid:31425,ppid:31424
I am father,pid:31424,ppid:31606
I am child,pid:31425,ppid:31424
I am child,pid:31425,ppid:31424
[eutoVM-4-13-centos 24921]$ I am child,pid:31425,ppid:1
I am child,pid:31425,ppid:1
I am child,pid:31425,ppid:1
I am child,pid:31425,ppid:1
I am child,pid:31425,ppid:1
······ 运行五秒后父进程退出子进程变成孤儿进程同时变成后台进程。此外子进程被PID为1的进程“领养”。
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
31606 31424 31424 31606 pts/1 31424 S 1001 0:00 ./myprocess
31424 31425 31424 31606 pts/1 31424 S 1001 0:00 ./myprocessPPID PID PGID SID TTY TPGID STAT UID TIME COMMAND1 31425 31424 31606 pts/1 31606 S 1001 0:00 ./myprocessPPID PID PGID SID TTY TPGID STAT UID TIME COMMAND1 31425 31424 31606 pts/1 31606 S 1001 0:00 ./myprocessPID为1的进程就是操作系统自己。
[eutoVM-4-13-centos 24921]$ ps ajx | head -1 ps ajx | grep 1 | grep -v grepPPID PID PGID SID TTY TPGID STAT UID TIME COMMAND0 1 1 1 ? -1 Ss 0 33:30 /usr/lib
/systemd/systemd --switched-root --system --deserialize 22