8种机械键盘轴体对比
本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?
Linux进程生命周期
什么是进程
进程是资源分配的单位,每个进程都有进程控制块(PCB)。
进程用task_strcut描述:1
2
3
4
5
6
7
8
9task_struct
{
pid
...
*mm
*fs
*files
*signal
}
上述代码块展示了task_struct中描述的关于进程的比较重要的资源,如:进程号、内存资源、文件系统资源、文件资源、信号资源等。
其中,Linux中的进程号pid是有限的,可以通过cat /proc/sys/kernel/pid_max来查看当前系统所允许的最大进程个数。
一个有趣的实验:通过Fork炸弹,可以使系统挂掉。即运行:(){:|:&};:
进程被如何管理
上节所示,进程用task_struct描述,而task_struct在linux中被多种数据结构描述:链表、树、哈希。用以满足不同的应用场景。
如果想表里所有进程,则使用链表;如果想知道进程间关系,则使用树;如果想通过pid快速检索一个进程,则使用哈希。
进程生命周期
用一张图总括linux中任务的生命周期:
从上图可以看出,任务总共有六个状态。
僵尸进程
基本概念
一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。
任何一个子进程(init除外)在exit()之后,并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构,等待父进程处理。这是每个 子进程在结束时都要经过的阶段。如果子进程在exit()之后,父进程没有来得及处理,这时用ps命令就能看到子进程的状态是“Z”。如果父进程能及时处理,可能用ps命令就来不及看到子进程的僵尸状态,但这并不等于子进程不经过僵尸状态。如果父进程在子进程结束之前退出,则子进程将由init接管。init将会以父进程的身份对僵尸状态的子进程进行处理。
问题及危害
在每个进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等。但是仍然为其保留一定的信息(包括进程号the process ID,退出状态the termination status of the process,运行时间the amount of CPU time taken by the process等)。直到父进程通过wait/waitpid来取时才释放。但这样就导致了问题,如果进程不调用wait/waitpid的话,那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免。
如何杀死僵尸进程
用kill是杀不死僵尸进程的。
杀死僵尸进程的方法有二:重启系统
杀掉该僵尸进程的父进程
停止状态与作业控制
停止态及任务停止工作,暂停了,且不占用cpu。
当收到STOP信号后,任务进入停止态,比如收到了ctrl+z,或者被gdb attach了。
其中ctrl+z属于作业控制。
深睡眠和浅睡眠
浅睡眠:可以被资源唤醒,也可以被信号唤醒。
深睡眠:只能被资源唤醒。
为何有了浅睡眠还要搞个深睡眠?考虑以下场景:如果执行到某个代码段,该代码段还在硬盘中,未被拷贝到内存中,则会产生一个pagefault,用以将该代码段读到内存中,接下来,linux会将该等待进程置位深度睡眠态。如果此时为浅度睡眠,则会相应signal,如果该signal的处理函数也未被读到内存,则又发生pagefault……这种情况处理起来太复杂了
初见fork
首先看一段程序:1
2
3
4
5
6
7
8main()
{
fork();
printf("hellorn");
fork();
printf("hellorn");
while(1);
}
上述程序会打印几个hello?答案是6个。
fork所执行的效果,既是一个进程进去,两个进程出来。