苏州怎么做网站排名优化,dede我的网站,电脑做视频的网站,vs2015做网站如何添加控件From: http://bbs.hx95.com/read-htm-tid-208094-fpage-2.html
R (TASK_RUNNING)#xff0c;可执行状态。 只有在该状态的进程才可能在CPU上运行。同一时刻可能有多个进程处于可执行状态#xff0c;这些进程的task_struct结构#xff08;进程控制块#xff09;被放入对…From: http://bbs.hx95.com/read-htm-tid-208094-fpage-2.html
R (TASK_RUNNING)可执行状态。 只有在该状态的进程才可能在CPU上运行。同一时刻可能有多个进程处于可执行状态这些进程的task_struct结构进程控制块被放入对应CPU的可执行队列中一个进程最多只能出现在一个CPU的可执行队列中。进程调度器从各个CPU的可执行队列中分别选择一个进程在该CPU上运行。 正在CPU上执行的进程定义为RUNNING状态、可执行但尚未被调度执行的进程定义为READY状态这两种状态统一为 TASK_RUNNING状态。 S (TASK_INTERRUPTIBLE)可中断的睡眠状态。 处于这个状态的进程因为等待某某事件的发生比如等待socket连接、等待信号量而被挂起。这些进程的task_struct结构被放入对应事件的等待队列中。当这些事件发生时由外部中断触发、或由其他进程触发对应的等待队列中的一个或多个进程将被唤醒。 进程列表中的绝大多数进程都处于TASK_INTERRUPTIBLE状态。CPU就这么一两个进程动辄几十上百个如果不是绝大多数进程都在睡眠CPU将会响应不过来。 D (TASK_UNINTERRUPTIBLE)不可中断的睡眠状态。 进程处于睡眠状态但是此刻进程是不可中断的。不可中断指的并不是CPU不响应外部硬件的中断而是指进程不响应异步信号。绝大多数情况下进程处在睡眠状态时总是应该能够响应异步信号的。 而TASK_UNINTERRUPTIBLE状态存在的意义在于进程对某些硬件进行操作时比如进程调用read系统调用对某个设备文件进行读操作而read系统调用最终执行到对应设备驱动的代码并与对应的物理设备进行交互可能需要使用TASK_UNINTERRUPTIBLE状态对进程进行保护以避免进程与设备交互的过程被打断造成设备陷入不可控的状态。这种情况下的TASK_UNINTERRUPTIBLE状态总是非常短暂的通过ps命令基本上不可能捕捉到。 linux系统中也存在容易捕捉的TASK_UNINTERRUPTIBLE状态。执行vfork系统调用后父进程将进入TASK_UNINTERRUPTIBLE状态直到子进程调用exit或exec。通过下面的代码就能得到处于TASK_UNINTERRUPTIBLE状态的进程 #include stdio.h #include unistd.h void main() { if (!vfork()); sleep(100); ruturn 0; } 编译运行然后ps一下 njsnjs:~/test$ ps -ax | grep a\.out 4371 pts/0 D 0:00 ./a.out 4372 pts/0 S 0:00 ./a.out 4374 pts/1 S 0:00 grep a.out 然后我们可以试验一下TASK_UNINTERRUPTIBLE状态的威力。不管kill还是kill -9这个TASK_UNINTERRUPTIBLE状态的父进程依然屹立不倒。 T (TASK_STOPPED or TASK_TRACED)暂停状态或跟踪状态。 向进程发送一个SIGSTOP信号它就会因响应该信号而进入TASK_STOPPED状态除非该进程本身处于TASK_UNINTERRUPTIBLE状态而不响应信号。SIGSTOP与SIGKILL信号一样是非常强制的。不允许用户进程通过signal系列的系统调用重新设置对应的信号处理函数。向进程发送一个SIGCONT信号可以让其从TASK_STOPPED状态恢复到TASK_RUNNING状态。 Z (TASK_DEAD - EXIT_ZOMBIE)退出状态进程成为僵尸进程。 进程在退出的过程中处于TASK_DEAD状态。 在这个退出过程中进程占有的所有资源将被回收除了task_struct结构以及少数资源以外。于是进程就只剩下task_struct这么个空壳故称为僵尸。之所以保留task_struct是因为task_struct里面保存了进程的退出码、以及一些统计信息。而其父进程很可能会关心这些信息。释放掉task_struct则需要建立一些新的数据结构以便让父进程找到它的子进程的退出信息。 父进程可以通过wait系列的系统调用如wait4、waitid来等待某个或某些子进程的退出并获取它的退出信息。然后wait系列的系统调用会顺便将子进程的尸体task_struct也释放掉。子进程在退出的过程中内核会给其父进程发送一个信号通知父进程来“收尸”。这个信号默认是SIGCHLD但是在通过clone系统调用创建子进程时可以设置这个信号。 通过下面的代码能够制造一个EXIT_ZOMBIE状态的进程 #include stdio.h #include unistd.h void main() { if (fork()); while(1) sleep(100); } 编译运行然后ps一下 njsnjs:~/test$ ps -ax | grep a\.out 10410 pts/0 S 0:00 ./a.out 10411 pts/0 Z 0:00 [a.out] 10413 pts/1 S 0:00 grep a.out 只要父进程不退出这个僵尸状态的子进程就一直存在。那么如果父进程退出了呢谁又来给子进程“收尸”当进程退出的时候会将它的所有子进程都托管给别的进程使之成为别的进程的子进程。托管给谁呢可能是退出进程所在进程组的下一个进程如果存在的话或者是1号进程。所以每个进程、每时每刻都有父进程存在。除非它是1号进程。 1号进程pid为1的进程又称init进程。linux系统启动后第一个被创建的用户态进程就是init进程。它有两项使命1、执行系统初始化脚本创建一系列的进程它们都是init进程的子孙2、在一个死循环中等待其子进程的退出事件并调用waitid系统调用来完成“收尸”工作init进程不会被暂停、也不会被杀死这是由内核来保证的。它在等待子进程退出的过程中处于TASK_INTERRUPTIBLE状态“收尸”过程中则处于TASK_RUNNING状态。