用户级线程 User Threads
- 线程管理(创建、资源申请、调度、通信等)
由user-level threads library “一手包办”,不靠OS内核 - 举例:Thread primary thread libraries
- JAVA threads
- POSIX pthreads
- Win32 threads
内核级线程 Kernel Threads
- 线程管理由操作系统内核的kernel-level threads实现
- 举例
- Windows XP/2000
- Solaris
用户线程要受内核支持,无需内核管理,而内核线程由操作系统直接支持和管理。
有些操作系统内核支持多线程,有些不支持(早期的一些)。有不同的模型。
多线程模型 Multithreading
- Many-to-One(OS不支持内核线程,程序包(在用户态)比如JAVA threads library对操作系统来说就是个单独的进程,程序包得到操作系统给的CPU,由这个包对多个线程做二次分配)
一个出错,其他线程都会受连累,交出CPU - One-to-One(OS内核支持多线程,一个用户态线程对应一个内核线程)
出错线程没有影响其它正常线程 - Many-to-Many(用户态有M个线程,内核态有N个线程)
- Two-level (包括Many-to-Many和One-to-One)
线程管理相对于进程管理带来的问题
-
fork()操作和exec()操作的意义有变
之前了解了进程中的fork,子进程继承了父进程的所有资源。线程里面的fork语义有什么变化?一个线程调用fork,仅仅复制调用线程呢?还是复制与调用线程同属于一个task的所有线程呢?这各有道理。
而exec()是一样的,exec()在进程中是子进程替换代码段,装入二进制文件并执行。那在线程里面,这里的代码段数据段是共享的,这样按照原来的exec()是不是影响到别的线程了?还是说只替换属于这个线程独立部分的代码?这也各有各的道理所在。
都是操作系统线程管理中需要处理的具体问题,都要明确给出答案。 -
撤销线程
在线程正常完成操作前,终止它,释放各种资源。至少有两种语义,马上撤销和不断检查它是否应该终止,检查到应该终止时候,才终止自己。 -
信号处理
进程与进程之间,通信就是进程整体处理,多线程情况下,信号发过来,哪个线程去响应? -
线程池 Thread pools
如果每次开一个线程就要创建一个线程处理请求,用完之后就会丢弃,这样在有大量高并发的情况下,无限制的线程会耗尽系统资源,解决方案是使用线程池。
在进程开始时创建一定数量的线程,并放入到池中等待工作。服务器收到请求时候,会唤醒池中的一个线程(如果有可用的线程),并将要处理的请求传递给它。一旦线程完成服务,它就会返回池中再等待工作。
这样有两个优点:- 使用现有的线程处理请求比等待创建新的线程要快
- 线程池限制了在任何时候可用线程的数量
网友评论