2010-08-24 3 views
12

Когда я звоню 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"); 
} 

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

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

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

Я использую Dev-C++ v4.9.9.2 и Pthreads-win32 v2.8.0.0 (связываннии libpthreadGC2.a).

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

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

+1

Почему вы не возвращаете 0; 'вместо' pthread_exit (NULL); '? –

+2

Я знаю, что я возвращаюсь или возвращаюсь. Я просто хочу знать, можно ли закончить основной поток, вызвав 'pthread_exit'. – user429788

+0

Возврат из main() очень отличается от работы pthread_exit(). Последний позволит оставшимся живым потокам закончить, а затем выйти с возвратным значением 0. Бывший немедленно прекратит все. –

ответ

12

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

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

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

+0

Тогда я думаю, что это должно быть законным в реализации win32 (http://sourceware.org/pthreads-win32/bugs.html). Я искал известную ошибку, которая объясняет это поведение, но я не мог ее найти. На мой взгляд, это либо плохое поведение, либо есть реальная причина, по которой я не должен называть 'pthread_exit' на' pthreads_win32'. Кто-нибудь может подтвердить любую из этих гипотез? – user429788

+0

@matasierra: Я добавил несколько подробностей к ответу. Кроме того, что на самом деле выполняется? – torak

+0

Первый 'printf' фактически распечатан, но второй - нет (как и ожидалось). Проблема в том, что программа не закончится. Он просто получает вид _frozen_. – user429788

12

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

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

0

При тестировании на Linux (выпуск CentOS Linux 7.2.1511 (Core)) я обнаружил, что действительно основная программа ждет продолжения «дочерних» потоков. Кроме того, я не смог пройти код возврата из основной, хотя он может быть указан в качестве аргумента для pthread_exit(), а Рауль вышесказанному всегда возвращается с кодом выхода 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 
Смежные вопросы