Skip to content

Commit 99512a5

Browse files
update lec11-p1-thread
1 parent a2ab820 commit 99512a5

File tree

1 file changed

+36
-28
lines changed

1 file changed

+36
-28
lines changed

lec11/p1-thread.md

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ main: end
361361
##### 用户态管理且用户态运行的线程
362362
363363
- 在用户态实现线程的管理与运行,操作系统感知不到这类线程的存在
364-
- POSIX Pthreads,Mach C-threads,Solaris threads
364+
- GNU Pth (Portable Threads),Mach C-threads,Solaris threads
365365
- 别名:用户态线程(User-level Thread)、绿色线程(Green Thread)、有栈协程(Stackful Coroutine)、纤程(Fiber)
366366
367367
![bg right:45% 100%](figs/usr-thread.png)
@@ -372,6 +372,8 @@ main: end
372372
373373
- 由一组用户级的线程库函数来完成线程的管理,包括线程的创建、终止、同步和调度等
374374
375+
- GNU Pth (Portable Threads),Mach C-threads,Solaris threads
376+
- 别名:用户态线程(User-level Thread)、绿色线程(Green Thread)、有栈协程(Stackful Coroutine)、纤程(Fiber)
375377
![bg right:45% 100%](figs/usr-thread.png)
376378
377379
---
@@ -443,12 +445,23 @@ main: end
443445
##### 内核态管理且用户态运行的线程
444446
445447
- 一个进程中可以包括多个线程
446-
- Windows内核的设计
447-
- rCore/uCore内核的设计
448-
- 一个进程中只包括一个线程
449-
- Linux内核的设计
448+
- Windows NT 内核支持线程,每个线程都是内核对象
449+
450+
- Linux-2.6 + glibc-2.3开始支持POSIX thread标准
451+
- rCore/uCore内核的设计
452+
- 主流:一个用户线程对应一个内核的线程控制块,由内核管理和调度
453+
![bg right:40% 100%](figs/kernel-thread.png)
450454
451-
![bg right:45% 100%](figs/kernel-thread.png)
455+
---
456+
457+
##### 线程的上下文切换
458+
459+
线程是调度的基本单位,而进程则是资源拥有的基本单位。
460+
461+
- 不同进程中的线程切换:进程上下文(如页表等)需要切换
462+
- 相同进程中的线程切换:虚拟内存等**进程资源**不需切换,只需要切换**线程的私有数据、寄存器**等不共享的数据
463+
464+
![bg right:40% 100%](figs/kernel-thread.png)
452465
453466
---
454467
@@ -470,6 +483,8 @@ main: end
470483
- 内存占用:多线程`fork()`会复制整个进程的地址空间,包括所有线程所拥有的栈、寄存器和锁等资源
471484
- 性能下降:多线程`fork()`的开销较大,可能会影响应用程序的性能
472485
486+
可采用:限制线程中调用 fork()、使用 pthread_atfork() 在 fork() 前后统一加/解锁来防止子进程死锁等方法,来避免这些问题。
487+
473488
<!--
474489
因此,在多线程应用程序中,建议谨慎使用 fork(),尤其是当涉及到共享资源和锁时。可以采用其他技术来实现进程间通信和同步,例如共享内存、消息队列和信号量等。
475490
-->
@@ -575,30 +590,21 @@ main: end
575590
576591
##### 轻量级进程:双态管理的线程
577592
578-
轻量级进程(Light-Weight Process,LWP)是内核支持的用户线程
579-
* 一个进程可有一个或多个 LWP,每个 LWP 是跟内核线程一对一映射的,也就是 LWP 都是由一个内核线程支持。
580-
* 在 LWP 之上也可使用用户线程。
593+
轻量级进程(Light-Weight Process,LWP)
594+
* 定义:LWP 是用户线程库与内核线程之间的中间数据结构,向用户线程库呈现为“可调度虚拟 CPU”。用户线程可被映射到一个或多个 LWP 上,由用户态调度器在这些 LWP 上切换执行。
595+
* 每个 LWP 是跟内核线程一对一映射的,即一个LWP 绑定到一个内核线程。
596+
* 一个进程可包含多个LWP,一个LWP 可对应多个用户线程,一个用户线程也可对应多个LWP。
581597
582598
---
583599
584600
##### 轻量级进程与用户线程的对应关系
585601
586-
- 1 : 1,即一个 LWP 对应 一个用户线程:Linux, JVM
587-
- 取消用户态管理,内核管理线程
588-
- N : 1,即一个 LWP 对应多个用户线程:与OS无关的Green Thread
589-
- 内核态仅管理包含多个线程的进程,用户态的线程运行时管理线程
590-
- M : N,即多个 LWP 对应多个用户线程:Solaris OS, Go runtime
591-
- 用户态线程运行时和内核协同进行管理
592-
593-
---
602+
- 1 : 1(主流),即一个用户线程对应一个LWP。如Linux内核管理和调度用户线程
603+
- M : 1(非主流),即多个用户线程对应一个LWP。如Green Thread,内核仅管理包含多个线程的进程,用户态的线程运行时管理线程。
604+
- M : N(非主流),即多个用户线程对应多个LWP。如Solaris OS通过用户态线程运行时和内核协同,对用户态线程进行管理和调度。
594605
595-
##### 轻量级进程实例
596-
597-
M : N线程模型
598-
- Solaris 操作系统+C线程运行时库
599-
- Go语言+Go运行时库+OS
600606
601-
![bg right:50% 100%](figs/lwp2.png)
607+
![bg right:40% 100%](figs/lwp2.png)
602608
603609
---
604610
@@ -613,12 +619,14 @@ M : N线程模型
613619
614620
---
615621
616-
##### 线程的上下文切换
617-
618-
线程是调度的基本单位,而进程则是资源拥有的基本单位。
622+
##### 轻量级进程实例(M : N线程模型)
623+
- Solaris 操作系统+C线程运行时库
624+
- 曾在 Solaris(≤ 8)、HP-UX(11i v1.6+)、AIX(4.3.1–7.3)、IRIX、Tru64 UNIX 中得到过真实应用
625+
- 实现复杂度高:调试和维护难度大
626+
- 性能不稳定:切换代价和同步开销往往抵消 M:N 本应带来的优势
627+
- 现代硬件多核/多处理器环境下,1:1 模型能更直接地映射并行需求
619628
620-
- 不同进程中的线程切换:进程上下文切换
621-
- 相同进程中的线程切换:虚拟内存等**进程资源**保持不动,只需要切换**线程的私有数据、寄存器**等不共享的数据
629+
![bg right:40% 100%](figs/lwp2.png)
622630
623631
---
624632

0 commit comments

Comments
 (0)