我对多处理器机器中posix线程的并发性有一些疑问。我在SO中发现了类似的问题,但没有找到最终的答案。
以下是我的理解。我想知道我是否正确。
Posix线程是用户级线程,内核不知道。
内核调度程序会将Process(及其所有线程)视为一个用于调度的实体。依次是线程库选择要运行的线程。它可以在可运行线程之间划分内核给定的cpu时间。
用户线程可以在不同的cpu内核上运行。即让线程T1和T2由Process(T)创建,那么T1可以在Cpu1中运行,而T2可以在Cpu2中运行,但是 它们不能同时运行 。
如果我的理解正确,请告诉我。
谢谢…
由于您用“ Linux”标记标记了您的问题,因此我将根据linux下的标准pthreads实现来回答它。如果您谈论的是“绿色”线程,它们是在VM /语言级别而不是在OS上调度的,那么您的答案通常是正确的。但是我下面的评论是关于Linux pthread的。
1)Posix线程是用户级线程,内核不知道。
不,这当然是不正确的。Linux内核和pthreads库一起工作以管理线程。内核执行上下文切换,调度,内存管理,缓存内存管理等。当然,还有其他管理是在用户级别完成的,但是如果没有内核,pthread的许多功能将丢失。
2)内核调度程序会将Process(及其所有线程)视为一个用于调度的实体。依次是线程库选择要运行的线程。它可以在可运行线程之间划分内核给定的cpu时间。
不,内核将每个进程线程视为一个实体。它有自己的时间划分规则,其中考虑了流程(和流程优先级),但是每个子流程线程都是可调度的实体。
3)用户线程可以在不同的cpu内核上运行。即让线程T1和T2由Process(T)创建,然后T1可以在Cpu1中运行,而T2可以在Cpu2中运行,但是它们不能同时运行。
否。多线程程序应同时执行。这就是为什么同步和互斥锁如此重要,以及为什么程序员忍受多线程编程的复杂性的原因。
向您证明这一点的一种方法是查看pswith -L选项的输出以显示关联的线程。 ps通常将多个线程进程包装到一行中,但是-L您可以看到内核为每个线程有一个单独的虚拟进程ID:
ps
-L
ps -ef | grep 20587 foo 20587 1 1 Apr09 ? 00:16:39 java -server -Xmx1536m ...
与
ps -eLf | grep 20587 foo 20587 1 20587 0 641 Apr09 ? 00:00:00 java -server -Xmx1536m ... foo 20587 1 20588 0 641 Apr09 ? 00:00:30 java -server -Xmx1536m ... foo 20587 1 20589 0 641 Apr09 ? 00:00:03 java -server -Xmx1536m ... ...
我不确定Linux线程是否仍会这样做,但是从历史上看,pthreads使用clone(2)系统调用来创建其自身的另一个线程副本:
clone(2)
与fork(2)不同,这些调用允许子进程与调用进程共享其执行上下文的一部分,例如内存空间,文件描述符表和信号处理程序表。
这与fork(2)创建另一个完整过程时使用的方法不同。
fork(2)