-1

在 CSAPP 书第 12.3 节中,他们说..

线程通过调用pthread_exit函数显式终止。如果主线程调用pthread_exit,它会等待所有其他对等线程终止,然后终止主线程和整个进程,返回值为 thread_return。

但是在pthread_exit的手册页中:https ://man7.org/linux/man-pages/man3/pthread_exit.3.html

从除主线程之外的任何线程的启动函数执行返回会导致对 pthread_exit() 的隐式调用,使用函数的返回值作为线程的退出状态。

为了允许其他线程继续执行,主线程应该通过调用 pthread_exit() 而不是 exit(3) 来终止。

关于pthread_exit的两个描述是不同的。第一个说主线程将等待对等点,但不是第二个。

因此我编写了一个代码来确保正确的属性。

(我借用了一些代码行当主线程退出时,其他线程是否也退出?

(感谢https://stackoverflow.com/users/959183/laifjei

在此处输入图像描述

由于pthread_cancel在pthread_exit之前调用,主线程成功取消 t1 线程,结果如下,

在此处输入图像描述

但是,当我将代码修改为 '42 line -> add //' 和 '44 line -> delete //' 时,主线程无法取消 t1,因为它已经终止。因此,以下结果看起来像,,

抱歉有些错误,比如 wq

最后,我得出结论,手册页的属性是正确的。我对吗?

为什么CSAPP书说“它等待所有其他对等线程终止”?

4

1 回答 1

1

关于 pthread_exit 的两个描述是不同的。第一个说主线程将等待对等点,但不是第二个。

没有太大的不同,也不是您可以通过大多数方式轻松区分的方式。

特别是,无论主线程是立即终止还是等待其他线程终止后才终止,该pthread_exit()函数就像exit()函数一样,它不返回pthread_exit()观察到在调用和结束之间插入到测试程序中的语句main没有被执行,确实会产生任何信息来帮助您确定线程终止的相对顺序。

出于这个原因,这个问题在很大程度上也没有实际意义。虽然确实有一些方法可以观察到差异,但它很少显着。

不过,这里有一个更好的例子:

#include <stdio.h>
#include <errno.h>
#include <pthread.h>

pthread_t main_thread;

void *wait_for_main(void *unused) {
    void *main_rval;

    // Wait for the main thread to terminate
    if ((errno = pthread_join(main_thread, &main_rval)) != 0) {
        perror("pthread_join");
    } else {
        fputs("The main thread was successfully joined\n", stderr);
    }
    fflush(stderr);
    return NULL;
}

int main(void) {
    pthread_t child_thread;

    main_thread = pthread_self();
    if ((errno = pthread_create(&child_thread, NULL, wait_for_main, NULL)) != 0) {
        perror("pthread_create");
    } else {
        fputs("The child thread was successfully started\n", stderr);
    }

    pthread_exit(NULL);
}

该程序运行成功,正在打印...

子线程启动成功
主线程加入成功

这表明主线程确实终止了(因为它已成功加入),而另一个线程随后继续运行(因为它将消息写入stderr)。

你继续问...

为什么CSAPP书说“它等待所有其他对等线程终止”?

......但除了科比、奥哈拉隆或他们的一位编辑之外,没有人能明确回答这个问题(也许不是全部——或任何——这些问题)。以下是一些可能性:

  • 这本书是错的。它发生了。
  • 这本书不清楚或不精确,因为它意味着等待成为整个程序、操作系统或“主线程以外的东西”的其他变体的“它”。

或者我实际的最佳猜测:

  • 这本书是从操作系统的角度描述行为,而 Pthreads 文档是从 C 语言的角度描述它。很可能作为进程的主要线程的 OS 线程确实是等待其他线程终止的东西,但它在运行程序中的 C 语言语义以pthread_exit(). 那就是这本书在谈论 pthread 实现细节,没有记录,可观察的 pthread 语义。
于 2021-05-22T18:09:49.007 回答