多处理器机器中posix线程的并发性

hac*_*ock 5 linux multithreading posix scheduling linux-kernel

我对多处理器机器中posix线程的并发性有一些疑问.我在SO中发现了类似的问题,但没有找到确凿的答案.

以下是我的理解.我想知道我是否正确.

  1. Posix线程是用户级线程,内核不知道它.

  2. 内核调度程序将Process(包含其所有线程)视为一个用于调度的实体.它是线程库,它反过来选择运行哪个线程.它可以在可运行的线程中分割内核给出的CPU时间.

  3. 用户线程可以在不同的cpu核心上运行.即让线程T1和T2由进程(T)创建,然后T1可以在Cpu1中运行,T2可以在Cpu2中运行但是它们不能同时运行.

如果我的理解正确,请告诉我.

谢谢...

Gra*_*ray 9

由于您使用"Linux"标记标记了您的问题,我将根据linux下的标准pthreads实现来回答它.如果您正在谈论"绿色"线程,这些线程是在VM /语言级而不是操作系统上安排的,那么您的答案大多是正确的.但我在下面的评论是关于Linux pthreads.

1)Posix线程是用户级线程,内核不知道它.

不,这当然不正确.Linux内核和pthreads库一起管理线程.内核执行上下文切换,调度,内存管理,缓存内存管理等.当然,在用户级别还有其他管理,但没有内核,pthreads的大部分功能都会丢失.

2)内核调度程序将Process(包含其所有线程)视为一个用于调度的实体.它是线程库,它反过来选择运行哪个线程.它可以在可运行的线程中分割内核给出的CPU时间.

不,内核将每个进程线程视为一个实体.它有自己的关于时间切片的规则,它将进程(和进程优先级)考虑在内,但每个子进程线程都是一个可调度的实体.

3)用户线程可以在不同的cpu核心上运行.即让线程T1和T2由进程(T)创建,然后T1可以在Cpu1中运行,T2可以在Cpu2中运行但是它们不能同时运行.

不可以.多线程程序需要并发执行.这就是为什么同步和互斥体如此重要以及程序员为什么忍受多线程编程的复杂性的原因.


向您证明这一点的一种方法是查看pswith -L选项的输出以显示关联的线程. ps通常将多个线程进程包装成一行,但-L您可以看到内核为每个线程都有一个单独的虚拟进程ID:

ps -ef | grep 20587
foo    20587     1  1 Apr09 ?        00:16:39 java -server -Xmx1536m ...
Run Code Online (Sandbox Code Playgroud)

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 ...
...
Run Code Online (Sandbox Code Playgroud)

我不确定Linux线程是否仍然这样做,但历史上pthreads使用clone(2)系统调用来创建自己的另一个线程副本:

与fork(2)不同,这些调用允许子进程与调用进程共享其执行上下文的一部分,例如内存空间,文件描述符表和信号处理程序表.

这与fork(2)创建另一个完整进程时使用的不同.


Ant*_*ams 5

POSIX未指定如何将创建的线程pthread_create安排到处理器核心上.这取决于实施.

但是,我希望在质量实现中有以下内容,这是当前版本的linux的情况:

  • 线程是完整的内核线程,由内核调度
  • 来自同一进程的线程可以在不同的处理器上并发运行

即所有3个编号的语句都与当前的linux实现有关,但理论上对于另一个符合POSIX的实现也是如此.