Подтвердить что ты не робот

Можно ли называть pthread_exit из main?

Когда я вызываю pthread_exit из main, программа никогда не заканчивается. Я ожидал, что программа закончится, так как я вышел из программы только в поток, но это не сработало. Кажется, он висел.

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

int main(int argc, char *argv[])
{
    printf("-one-\n");

    pthread_exit(NULL);

    printf("-two-\n");
}

Проводник процессов показывает, что поток (только) находится в состоянии Wait:DelayExecution.

Согласно документации pthread_exit:

Процесс должен выйти с выходом статус 0 после последнего потока были прекращены. Поведение должно быть как если бы реализация называлась exit() с нулевым аргументом в потоке время окончания.

Я использую Dev-С++ v4.9.9.2 и pthreads-win32 v2.8.0.0 (ссылка на libpthreadGC2.a).

Библиотека кажется ОК (например, вызов pthread_self или pthread_create из main отлично работает).

Есть ли причина, по которой я не должен называть pthread_exit от main?

4b9b3361

Ответ 1

Хорошо, что он определенно легален в реализации linux pthreads, см. раздел примечаний в pthreads_exit. В нем указано

Чтобы другие потоки могли продолжить выполнение, основной поток должен завершиться вызывая pthread_exit(), а не exit (3).

Далее, посмотрите на исходный код здесь (torwads the end) показывает, что он примерно переводится как _endthread или _endthreadex. Документация здесь для них не упоминает о том, что вы не вызываете ее в исходном потоке.

Ответ 2

Это полностью законное и предполагаемое поведение. Весь процесс заканчивается только тогда, когда либо завершаются все потоки, либо exit вызывается явно или неявно.

Нормальный возврат из main эквивалентен вызову exit. Если вы закончите main с помощью pthread_exit, вы прямо заявляете, что хотите, чтобы другие потоки продолжались.

Ответ 3

При тестировании на Linux (выпуск CentOS Linux 7.2.1511 (Core)) я обнаружил, что действительно основная программа ждет продолжения "дочерних" потоков. Также я не смог передать код возврата из main, хотя он может быть указан как аргумент для pthread_exit(), как сказал Raul выше, он всегда возвращается с кодом выхода 0:

retval=3;
pthread_exit(&retval);

Мы также заметили сообщение об ошибке при использовании компилятора Clang (версия 3.4.2) и параметров дезинфицирующего средства:

==5811==ERROR: AddressSanitizer: attempting free on address which was not malloc()-ed: 0x7f4c090321d0 in thread T0
#0 0x7f4c08be3e29 in __interceptor_free (/home/karstenburger/tests/libc/pthread_exit_in_main/a+0x65e29)
#1 0x7f4c08333358 in free_key_mem (/lib64/libdl.so.2+0x1358)
#2 0x7f4c08745bc1 in __nptl_deallocate_tsd (/lib64/libpthread.so.0+0x7bc1)
#3 0x7f4c07771b38 in __libc_start_main (/lib64/libc.so.6+0x21b38)
#4 0x7f4c08bfa08c in _start (/home/karstenburger/tests/libc/pthread_exit_in_main/a+0x7c08c)

AddressSanitizer can not describe address in more detail (wild memory access suspected).
SUMMARY: AddressSanitizer: bad-free ??:0 __interceptor_free
==5811==ABORTING