论进程和线程的不同

来源:互联网 发布:java如何实现线程 编辑:程序博客网 时间:2024/05/16 09:38

我们应该去保持一个明确地认识对于线程。太多的人似乎带有对线程和进程的迷惑。以下的讨论并没有反应出当前Linux的目前状态,然后也是一次高级的讨论。
进程和线程仅仅只是一段上下文。
上下文仅仅是所有状态的一个集合。例如CPU状态(如寄存器状态)、MMU状态(页面状态)、权限状态(euid,egid)、还有各种通信状态(已经打开文件的状态,信号handler表的状态)。
传统地来说,进程和线程的不同主要是线程可能有些其他极少的状态剩余都来自于进程。然后这样仅仅这时上下文状态分配的一个方式,不能就说这个方式就是对的。限制你自己的显然这时这个愚蠢的想法。
对于Linux来说,没有一个东西称为线程或者进程。有的仅仅只是一个上下文的集合。不同的上下文能够分享它们的部分上下文给彼此,而且分享的上下文是由传统的进程或线程建立的,并且应该真真的只把它当做上下文的一个子集罢了(它是一个重要的子集,只不过这个重要性并不来自于设计,而是来自于标准,我们明显地仅仅只是想让能够符合标准的线程程序可以在Linux上运行而已)
简而言之:
别去在乱想关于进程/线程的想法了。内核应该被设计成关于上下文的,然后线程库能够暴露出有限的线程接口给那些想用接口去查看这个上下文的用户即可。
举一个可能当你认为上下文就是进程/线程的列子:
你能够写一个外部的程序,这个外部程序是不可能在传统的Unix中作为一个线程的。(这个很蠢的列子,但是这个想法可以使你有些想法在大脑不再只限制于传统的Unix线程的设置)

做一个:
clone(CLONE_VM|CLONE_FS); 子进程继承父进程的地址空间和文件描述符表
child : execve(“cd”)
/execve函数将会使子进程分离父进程的地址空间,所以我们用共享clone_vm 去确保这个 clone调用更快*/
上面的工作只是因为你不让你再有进程/线程的想法。思考一个web服务器,cgi脚本可以作为一个程序的替换。你不能让一个传统的线程去做,因为线程总是不得不分享整个地址空间,所以你将不得不自己去回复web服务器的请求。
作为替换思考下这个 “上下文”问题,你的task(上下文集合)现在能够去选择去替换一个外部程序,如果它们想这样做的话或者它们能分享任何东西给父进程除了文件描述符外(以至于 子“线程”能够打开大量的文件描述符而不需要父线程去关心它们,在子线程退出的时候它们都会自动关闭,但是它不能被父线程再使用)。

思考下 “inetd”这个线程。当你想 低消耗的去 fork+exec时,当你想写一个多线程的网络服务时,你可以使用 CLONE_VM (共享地址空间的clone调用)去代替fork。接着这个子线程可能execve如果它是一个外部服务的话或者内部服务的话,它仅仅去做什么而去退出。

你不能做这个通过线程/进程。

COE: context of execution 上下文环境

原创粉丝点击