进程因为等待某种条件就绪,而导致的一种不推进的状态
操作系统对于磁盘、网卡、显卡等 资源通过 先描述,在组织进行管理,把设备用结构体描述起来,再用链表组织起来
管理的本质具体解释点击这里
存在大量的进程,操作系统要进行管理,也要先描述,在组织,就存在了大量的task_struct的结构体,每一个进程都是由task_struct定义出来的对象
进程组成的理解点击这里
阻塞:阻塞就是不被调度
一定是因为当前进程等待某种资源就绪
一定是进程task_struct结构体需要在某种操作系统管理的资源下进行排队
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 */ };
struct task_struct { int status;//0代表R状态 1代表s状态 4代表T状态 //.... }
task_struct 是一个结构体,内部会包含各种属性,就有状态,通过0、1、2等数字找到对应的进程状态
不一定
每个进程当中有自己的运行队列,只要该进程在队列中进行排队,运行的进程就会在运行的队列中排队,CPU调度进程时,从队列中挑选指定的进程运行就可以了,这种运行状态就叫做R状态
R状态不直接代表进程在运行,代表该进程在运行队列中排队
创建makefile并输入如下内容
1 mytest:test.c//nakefile 2 gcc -o mytest test.c 3 .PHONY:clean 4 clean: 5 rm -f mytest
创建test.c并输入如下内容
#include//test.c 2 int main() 3 { 4 while(1) 5 { 6 printf("我在运行吗\n"); 7 } 8 return 0; 9 }
[yzq@VM-8-8-centos my]$ make gcc -o mytest test.c [yzq@VM-8-8-centos my]$ ./mytest
make产生可执行程序mytest,./mytest执行可执行程序
赋值SSH渠道生成终端2
在保证终端1中的mytest运行的情况下,在终端2中输入指令ps axj | head -1 && ps axj | grep mytest | grep -v grep
创建终端的方法及指令具体含义点击这里
[yzq@VM-8-8-centos my]$ ps axj | head -1 && ps axj | grep mytest | grep -v grep PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 25615 30533 30533 25615 pts/0 30533 S+ 1002 0:00 ./mytest
发现此时进程状态为S+ (+号后面会说)
S称为休眠状态,不是R状态
test.c代码修改如下
#include//test.c 2 int main() 3 { 4 while(1) 5 { 6 // printf("我在运行吗\n"); 7 } 8 return 0; 9 }
在保证终端1中的mytest运行的情况下,在终端2中再次输入指令ps axj | head -1 && ps axj | grep mytest | grep -v grep
[yzq@VM-8-8-centos my]$ ps axj | head -1 && ps axj | grep mytest | grep -v grep PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 25615 31695 31695 25615 pts/0 31695 R+ 1002 0:10 ./mytest
本质是一种阻塞状态
修改test.c代码如下
1 #include 2 int main() 3 { 4 while(1) 5 { 6 int b=0; 7 scanf("%d",&b); 8 printf("%d\n",b); 9 } 10 return 0; 11 }
在保证终端1中的mytest运行的情况下,在终端2中再次输入指令ps axj | head -1 && ps axj | grep mytest | grep -v grep
[yzq@VM-8-8-centos my]$ ps axj | head -1 && ps axj | grep mytest | grep -v grep PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 25615 5793 5793 25615 pts/0 5793 S+ 1002 0:00 ./mytest
[yzq@VM-8-8-centos my]$ ./mytest 10 10 ^C//可以被终止
ctrl c
,终止mytest运行,S状态被终止想要往磁盘写入100MB的数据,由于磁盘写入数据很慢,所以进程把自己设置成阻塞状态,若内存资源特别紧张,操作系统就想要把这个阻塞状态的进程干掉,可是此时磁盘依旧还在写入数据,这样做就会使磁盘写入数据失败,最终就会使100MB的数据丢失
[yzq@VM-8-8-centos my]$ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) 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
test.c内容如下
1 #include #include 2 int main() 3 { 4 int count=0; 5 while(1) 6 { 7 printf("还在运行吗:%d\n",count++); sleep(1); 8 } 9 return 0; 10 }
保证在保证终端1中的mytest运行的情况下,在终端2中再次输入指令ps axj | head -1 && ps axj | grep mytest | grep -v grep
,并输入 kill-19+PID值
,终端1自动停止运行
[yzq@VM-8-8-centos my]$ ps axj | head -1 && ps axj | grep mytest | grep -v grep PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 25615 14791 14791 25615 pts/0 14791 S+ 1002 0:00 ./mytest
再次在终端2中查询进程,发现进程状态由S+变为T
若想让进程继续运行,在终端2中使用 kill -18 +PID值
yzq@VM-8-8-centos my]$ ps axj | head -1 && ps axj | grep mytest | grep -v grep PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 25615 14791 14791 25615 pts/0 25615 S 1002 0:00 ./mytest
在终端1使用ctrl c,程序不停止了
进程状态带+,进程是在前台运行的,可以使用ctrl c 终止
进程状态不带+,进程是在后台运行的,可以正常执行shell指令,但在后台继续还会执行自己的代码
此时若想终止进程,使用 kill -9 +PID值
干掉进程
用于判定进程结果是否正确 echo $?
修改test.c的内容如下
include 2 #include 3 int main() 4 { 5 int count=2; 6 if(count==2) 7 { 8 return 0; 9 } 10 else 11 { 12 return 4; 13 } 14 } ~
使用make生成可执行程序mytest,./mytest执行可执行程序
[yzq@VM-8-8-centos my]$ make gcc -o mytest test.c [yzq@VM-8-8-centos my]$ ./mytest [yzq@VM-8-8-centos my]$ echo $? 0
如果一个进程退出了,立马X状态,立马退出,你作为父进程,有没有机会拿到退出结果呢?
如何让我们看到僵尸状态呢?
修改test.c内容如下
#include 2 #include 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 else if(id>0) 16 { 17 //父进程 18 while(1) 19 { 20 printf("我是父进程,我在运行,pid:%d,ppid:%d",getpid(),getppid()); 21 sleep(1); 22 } 23 } }
保证在保证终端1中的mytest运行的情况下,在终端2中再次输入指令ps axj | head -1 && ps axj | grep mytest | grep -v grep
[yzq@VM-8-8-centos my]$ ps axj | head -1 && ps axj | grep mytest | grep -v grep PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 25615 18251 18251 25615 pts/0 18251 S+ 1002 0:00 ./mytest 18251 18252 18251 25615 pts/0 18251 S+ 1002 0:00 ./mytest [yzq@VM-8-8-centos my]$ kill -9 18252 [yzq@VM-8-8-centos my]$ ps axj | head -1 && ps axj | grep mytest | grep -v grep PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 25615 18251 18251 25615 pts/0 18251 S+ 1002 0:00 ./mytest 18251 18252 18251 25615 pts/0 18251 Z+ 1002 0:00 [mytest]
kill - 9 +PID值
将子进程干掉后,再次使用指令查询进程,发现子进程为僵尸状态,父进程为S+