Properties of pthread_exit function : which one is right?

683 views Asked by At

In the CSAPP book Section 12.3, They said..

The thread terminates explicitly by calling the pthread_exit function. If the main thread calls pthread_exit, it waits for all other peer threads to terminate and then terminates main thread and the entire process with a return value of thread_return.

However in the man page of pthread_exit : https://man7.org/linux/man-pages/man3/pthread_exit.3.html

Performing a return from the start function of any thread other than the main thread results in an implicit call to pthread_exit(), using the function's return value as the thread's exit status.

To allow other threads to continue execution, the main thread should terminate by calling pthread_exit() rather than exit(3).

Two descriptions about pthread_exit are different. First one said main thread will wait for peer but not on second.

Therefore I write a code to ensure correct property.

(I borrow some code lines from When the main thread exits, do other threads also exit?)

(Thanks to https://stackoverflow.com/users/959183/laifjei)

enter image description here

Since pthread_cancel is called before pthread_exit, main thread cancel t1 thread successfully and the result is like,,

enter image description here

However, when I modify a code as '42 line -> add //' and '44 line -> delete //', main thread cannot cancel t1 since it was already terminated. Therefore the following result is looks like,,

sorry for some mistakes like wq

Finally, I conclude that man page's property is correct. Am I right?

Why does CSAPP book said that "it waits for all other peer threads to terminate"?

1

There are 1 answers

0
John Bollinger On BEST ANSWER

Two descriptions about pthread_exit are different. First one said main thread will wait for peer but not on second.

Not very different, and not in a way that you can easily distinguish by most means.

In particular, regardless of whether the main thread terminates immediately or waits for other threads to terminate before doing so, the pthread_exit() function is like the exit() function in that it does not return. Observing that statements inserted into your test program between the pthread_exit() call and the end of main are not executed does yield any information that helps you determine the relative sequence of thread terminations.

For that reason, the question is also largely moot. Although there indeed are ways in which the difference can be observed, it is rarely significant.

Nevertheless, here's a better example:

#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);
}

That program runs successfully, printing ...

The child thread was successfully started
The main thread was successfully joined

This shows that the main thread indeed terminated (because it was successfully joined), and that the other thread continued to run afterward (because it wrote its message to stderr).

You go on to ask ...

Why does CSAPP book said that "it waits for all other peer threads to terminate"?

... but no one other than Bryant, O'Hallaron, or one of their editors could definitively answer the question (and maybe not all -- or any -- of those). Here are some possibilities:

  • The book is just wrong. It happens.
  • The book is unclear or imprecise, in that it means the "it" that waits to be the overall program, the operating system, or some other variation on "something other than the main thread".

Or my actual best guess:

  • The book is is describing behavior from an operating system perspective, whereas the Pthreads documentation is describing it from a C-language perspective. It may well be that the OS thread that is the process's main one indeed is the thing that waits for others to terminate, but its C-language semantics within the running program terminate with the pthread_exit(). That is the book is talking about pthread implementation details, not documented, observable pthread semantics.