回顾总结
process and thread
process是操作系统调度的基本单位,一个程序可以理解为一个进程。
thread是process的子process,是process调度的基本单位。
从调度角度理解process和thread
我们知道操作系统调度的时候是以process为单位的,即当我们的程序是单thread的process时,那在这个process获得cpu的时间片时,这个thread能够获得全部的这个时间片。在内核中,我们维护着一个process的table,来记录每个process的基本信息,根据不同的调度方式来使用这个信息或者不使用。
当一个process拥有多个thread时,如何调度thread呢?
两种情况则有不同的调度方式。当为内核态的thread时,即此时的thread可以称之为轻量级的process,这个时候内核来维护一个thread table和process table相似。同时操作系统来调度thread,就像调度process一样。当为用户态的线程时,那么操作系统感受不到多个thread的存在,因为此时操作系统调度的对象是process,一个process中有多少个thread他不关心,所以当一个process得到CPU时间片后,他会自己来调度thread。
了解他们两个基本工作方式后,应该清楚这两种线程的主要区别:调度者是谁?各个的优缺点是什么?在JAVA中使用的哪种thread?Golang中goroutine是如何对应到我们操作系统的调度单位上去的?
process and thread
process是操作系统调度的基本单位,一个程序可以理解为一个进程。
thread是process的子process,是process调度的基本单位。
从调度角度理解process和thread
我们知道操作系统调度的时候是以process为单位的,即当我们的程序是单thread的process时,那在这个process获得cpu的时间片时,这个thread能够获得全部的这个时间片。在内核中,我们维护着一个process的table,来记录每个process的基本信息,根据不同的调度方式来使用这个信息或者不使用。
当一个process拥有多个thread时,如何调度thread呢?
- 当thread为内核态thread时。
- 当thread为用户态thread时。
- 混合实现不做讨论
两种情况则有不同的调度方式。当为内核态的thread时,即此时的thread可以称之为轻量级的process,这个时候内核来维护一个thread table和process table相似。同时操作系统来调度thread,就像调度process一样。当为用户态的线程时,那么操作系统感受不到多个thread的存在,因为此时操作系统调度的对象是process,一个process中有多少个thread他不关心,所以当一个process得到CPU时间片后,他会自己来调度thread。
了解他们两个基本工作方式后,应该清楚这两种线程的主要区别:调度者是谁?各个的优缺点是什么?在JAVA中使用的哪种thread?Golang中goroutine是如何对应到我们操作系统的调度单位上去的?
- 调度者。 内核态的thread:内核。 用户态的thread:process
- 内核态thread的优点:在单个thread进行syscall而阻塞 时(一个线程不可以即运行代码,又能进行syscall),操作系统可以切换到同process中或者其他process下一个可以执行的thread,而不必阻塞,然而用户态的thread在进行syscall时,整个process下的thread都会阻塞。用户态的thread优点是在进行thread切换时消耗非常小,因为他不需要像内核态的thread那样需要陷入一次内核。
- Java中根据不同JVM而视情况决定,一般来说是1:1的模型,即JVM中的线程和操作系统的thread一一对应。理解这一点我们可以清楚,java的thread也不是可以无限制的增长(内核中thread table的大小是有限制的),而且创建一个thread的消耗也很大。
- Gorouting中的有一个参数GOMAXPROCS (The GOMAXPROCS variable limits the number of operating system threads that can execute user-level Go code simultaneously) 也就是这些goroutine是对于thread是N:1的模型,因为goroutine是由一个叫做context的结构来管理,context挂载一个thread,一次次来把当前可运行的goroutine压栈进行运行。当一个goroutine进行syscall时,当前context就只保留这么一个goroutine,scheduler来保证有下一个或者说有足够context来执行其他goroutine。详见:go-scheduler
Comments
Post a Comment