2010-05-12 144 views
9

我对线程有点新,所以你不得不原谅这个问题的天真。pthread_join是如何实现的?

pthread_join是如何实现的?它是如何影响线程调度的?

我总是使用while循环实现图片pthread_join,只是导致调用线程退出,直到目标线程完成。像这样(非常近似的伪代码):

 

atomic bool done; 

thread_run { 

    do_stuff(); 
    done = true; 

} 

thread_join { 

    while(!done) { 
     thread_yield(); 
    // basically, make the thread that calls "join" on 
    // our thread yield until our thread completes 
    } 
} 

这是一个准确的描述,还是我大大简化了过程?

干杯!

回答

3

是的,这是一般的想法。有关特定实施的详细信息,请参阅glibc

+2

他的代码和真实代码之间唯一真正的巨大差异是如果有备用核心,他的代码会导致加入的线程烧掉100%的CPU。 – 2011-08-30 13:10:38

4

pthread_join可能在内部实现为等待线程退出时触发的信号量,无论是在调用pthread_exit还是在其主函数退出时触发。

在任何情况下,glibc的源代码可用,尝试谷歌代码搜索(我看到一些资料性的东西在里面)

+0

https://sourceware.org/git/?p=glibc.git;a=blob;f=nptl/pthread_join.c;h=6a87a8b329c3e34a57d65e86d45fa97a5fdb2fe2;hb=master#l89的是神奇之处就行了。 – Benoit 2017-06-07 06:30:52

1

线程通常具有与之相关联的小结构,线程上下文。该结构可以塞满使线程“工作”所需的所有数据。

例如,数据结构的根需要访问该线程的线程特定的键,并且在它关闭时迭代它们以清除它们。

该结构中通常有一个类似于互斥体的锁,对于不同的部分可能有多个锁。

线程上下文可以有一个小字段在终止线程可以放置其退出状态。 (void *pthread_exit返回或从线程函数返回。)

线程上下文还可以指示线程的状态(尚未创建,正在运行,已停止)。

可能存在一个同步原语,例如条件变量或信号量,在准备终止状态并指示它正在终止之后,线程可以使用该同步原语kick

pthread_join函数可以等待该同步原语。一旦等待完成,该函数可以触发该线程的资源清除,并将状态提取出来。

线程在发出加入信号后继续执行。要做到这一点,它必须继续有一个堆栈的上下文。在那之后,系统必须解决在后台干净地停止线程的问题。

线程的用户空间实现可以将其推迟到内核。例如。一些信号可能熄灭或者表示线程已经完成。此时,用户空间知道线程不可能再使用堆栈,并且可以回收它。

在内核中,调度程序可以“吃”一个线程。该线程可以调用调度程序中的一些函数,该函数在清除大部分资源后永远不会返回。它将线程标记为死亡并将上下文切换到另一个线程。线程的堆栈永远不会再被使用(因为该函数永远不会返回),并且可以回收它的任务结构以及任何附加的东西。