linux 进程,线程

一、概念

进程包含很多资源,如打开的文件,挂起的信号,内核内部数据,处理器状态,一个或多个具有内存映射的内存地址空间及一个或多个执行线程。用来存放全局变量的数据段等。内核需要管理所有的细节。

线程,是在进程中活动的对象,每个线程都拥有一个独立的程序计数器,进程栈和一组进程寄存器。

进程描述符(task_struct)是任务队列(双向循环链表中)的类型。

二、进程的五种状态:

运行态:或者正在执行,或者在运行队列中等待执行

可中断:进程正在睡眠(阻塞),等待某些条件的达成。一旦达到这些条件,会变成运行态。

不可中断:除了此状态不会受到信号干扰,这个状态与可打断状态相同。

被跟踪态:例如ptrace对调试程序进行跟踪

停止状态:进程停止执行。

三、进程家族树

进程之间是继承关系,所有系统都是pid为1的init进程的后代。内核在系统启动的最后阶段启动init进程。该进程读取系统的初始化脚本,并执行其他的相关程序。

四、进程创建

1、首先:fork()通过拷贝当前进程创建一个子进程。子进程与父进程的区别仅仅在于PID,PPID(父进程的进程号)和某些资源和统计量(如:挂起的信号)

2、exec()函数负责读取可执行文件并将其载入地址空间开始运行。

写时拷贝:

clone():clone()系统调用fork()

fork():传统的fork()系统调用直接把所有的资源复制给新创建的进程,这种过程过于简单并且效率低下。也许拷贝的数据并不共享。写时拷贝是一种可以推迟甚至免除拷贝数据的技术。内核此时并不复制整个地址空间。而是让父进程和子进程共享同一个拷贝。

vfork():不拷贝父进程的页表项

五、线程创建:

linux,从内核的角度来说:它并没有线程这个概念,linux把所有的线程都当做进程来实现。只是共享某些资源,如地址空间。

clone()时需要传递一些参数标志来指明需要共享的资源。

六、进程终结:

调用do_exit()之后,尽管线程已经僵死不能再运行了,但是系统还保留了它的进程描述符。这个可以让系统有办法在子进程终结后仍能获得它的进程。进程终结时所需的清理工作和进程描述符的删除时被分开执行的。

孤儿进程:

如果父进程在子进程之前退出,必须有机制来保证子进程能找到一个新的父亲,否则这些成为孤儿的进程就会再退出时处于僵死状态。白白的耗费内存。解决方法是在当前线程组中找一个线程作为父亲。如果不行,就让init做它们的父进程。

猜你喜欢

转载自blog.csdn.net/qq_36183935/article/details/81276930