pthread_join是如何实现的?

时间:2010-05-12 18:57:20

标签: linux multithreading pthreads scheduling

我对线程有点新意,所以你必须原谅这个问题的天真。

如何实现pthread_join以及它如何影响线程调度?

我总是想象pthread_join用while循环实现,只是让调用线程屈服,直到目标线程完成。像这样(非常近似的伪代码):


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 个答案:

答案 0 :(得分:4)

pthread_join可能在内部实现为等待信号量的等待,当信号调用pthread_exit或其主函数退出时,该信号量将在线程退出时触发。

在任何情况下,glibc的源代码都可用,请尝试谷歌代码搜索(我在那里看到了一些信息丰富的东西)

答案 1 :(得分:3)

是的,这是一般的想法。有关特定实现的血腥细节,请查看glibc

答案 2 :(得分:1)

线程通常有一个与之关联的小结构,即线程上下文。该结构可以填充使线程“工作”所需的所有数据。

例如,数据结构的根需要访问该线程的特定于线程的密钥,并在它被关闭时迭代它们以清理它们。

在该结构中通常存在类似互斥锁的锁,并且对于不同的部分可能不止一个。

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

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

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

pthread_join函数可以等待该同步原语。等待完成后,除了拉出状态外,该函数还可以触发该线程的资源清理。

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

线程的用户空间实现可以将其推迟到内核。例如。某些信号可能会消失或表示线程已完成的任何信号。此时,用户空间知道线程不再可能正在使用其堆栈并且可以回收它。

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