Skip to content

Latest commit

 

History

History
10 lines (5 loc) · 2.55 KB

q9.md

File metadata and controls

10 lines (5 loc) · 2.55 KB

为什么说Linux没有线程的概念?

学过操作系统的人都会知道,进程是资源分配的单元,线程是调度的基本单位,如果更深入一点的话,你也会听说一些观点,比如说在Linux是没有线程的概念的,如果你现在听的比较迷茫的话,那么恭喜你,这篇文章就是为你准备的。

首先树立一个观点,在Linux里面确实是没有线程这个概念的,也就是说,Linux并没有为线程这个概念抽象出来任何的数据结构,也未给线程实现任何的调度方案。这是为什么呢?因为在Linux诞生的时候,根本就还没有出现线程这个概念,但是随着历史进程的发展,人们渐渐意识到进程的一些缺陷(进程的切换实在是太太太耗时了,而且进程一旦切换TLB和Cache全部得刷新),从而发明出了线程这个概念,但是要修改一个操作系统来支持这个新概念,那可不是一件容易的事情,但是里面用了一些trick罢了,从Linux2.6的内核版本开始,支持了“线程”这个概念,那么到底是怎么实现的呢?其实仍然和原来一样,用进程这个数据结构来实现线程,怎么说呢?也就是说线程的数据结构跟线程一样。wtf?你在逗我?然而事实就是这样。CS嘛,只要满足了你的要求,你管我是怎么实现的,只要跟你所想的要求一致就可以了。当然我们这里说的都是内核线程。用户线程没啥好说的,直接用库实现就好了。所以,在Linux,线程也称为轻量级进程(LWP)。

Linux是如何创建线程的呢?是通过clone这个系统调用,创建一个和父进程共享上下文的进程。等等,你是不是感觉跟fork好像?没错,就是很像,而且clone也直接或者间接用到了fork。再来说一下,为什么我还是感觉受到了欺骗,写过OS的人应该都用到了COW这种技术,也就是说,在实现fork的时候,我们不会将父进程的所有空间都拷贝,而是先跟父进程共享,怎么做到的呢?通过页表映射就可以了,将相同的虚拟地址映射到同一块物理空间去(没听说过?那快去看看COW吧),直到需要修改的时候,子进程才会重新申请内存然后修改,那么你会问了,既然有COW,那么是不是线程是不是也是通过COw实现的呢?nonono,虽然COW可以极大的改善性能,但是拷贝页表同样需要时间,而在创建线程的时候,我们甚至不需要拷贝页表,直接共用同一个页表就好啦!!