代码之家  ›  专栏  ›  技术社区  ›  Tom

pthread_join是如何实现的?

  •  10
  • Tom  · 技术社区  · 14 年前

    我对穿线有点陌生,所以你必须原谅这个问题的幼稚。

    如何 pthread_join 实现了,它如何影响线程调度?

    我一直在拍照 pthRead连接 使用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 回复  |  直到 12 年前
        1
  •  3
  •   Nikolai Fetissov    14 年前

    是的,这是一般的想法。有关特定实现的详细信息,请查看 glibc .

        2
  •  4
  •   MarkR    14 年前

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

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

        3
  •  1
  •   Kaz    12 年前

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

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

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

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

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

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

    这个 pthread_join 函数可以等待该同步原语。一旦等待完成,函数就可以触发该线程的资源清理,并拉出状态。

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

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

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