2016-08-28 16 views
1

Я пытаюсь сделать код потока самоочистки для освобождения ресурсов pthread_t, если я завершаю всю программу из бокового потока с помощью pthread_detach, но я все еще получаю отчеты об утечках памяти из valgrind с возможно потерянными байтами. Вот мой пример фрагмент кода:Получение утечек Даже после pthread_detach

pthread_t main_thread; 
pthread_t second_thread; 

void* thread_func() { 
    pthread_detach(pthread_self()); 
    exit(0); 
} 

int main() { 
    main_thread = pthread_self(); // record main thread in case needed later 
    pthread_create(&second_thread, NULL, thread_func, NULL); 
    while(1); // making main thread wait using a busy-wait (in case pthread_join) interferes 
       // with pthread_detach (that's another question though: does pthread_join called 
       // from another thread overlaps with pthread_detach from the same thread?) 


} 


Может кто-нибудь, пожалуйста, помогите мне указать, где я забыл освободить все выделенные ресурсы?

ответ

0

Итак, я просто нашел удивительное решение проблемы, с которой я столкнулся днями назад, и хотел бы поделиться ею.

Напоминание о том, что является исходной проблемой: проблема заключается в том, как очистить утечки потоков после вызова полного завершения процесса (это не будет фактическая утечка в производственном коде, но это всего лишь сделать valgrind для пример, счастливый !!).

Так что решение я придумал это:

сделать основной поток так же, как любой другой поток, создавая поток для всего «основной» нить (я знаю, что это увеличит использование памяти, и это будет не очень эффективно). Фактический основной поток будет постоянно проверять любой выходной сигнал, отправленный из любого потока, и если это так, очистите все потоки и просто выйдите. Другие потоки будут посылать сигнал выхода, когда это необходимо, и будут ждать, пока фактический основной поток очистит их (включая основной поток макета, который содержит заданный код основного потока).

Вот псевдокод, чтобы иллюстрировать то, что я уже упоминал выше:

threadId1; 
threadId2; 
mainThreadId; 
willExit = false; 
exitStatusCode; 
mainThreadArgs; 

exit_cleanup(exitStatusCodeArg) { 
    exitStatusCode = exitStatusArg; 
    willExit = true; 
    while(true); 
} 

threadFunc1() { 
    // Example thread code 1 
    exit_cleanup(0); 
} 

threadFunc2() { 
    // Example thread code 2 
    if (/*some error*/) 
     exit_cleanup(-1); 
} 

mainThreadFunc() { 
    // some code (could be long, and may create side threads here) 

    // by default, main thread should call exit_cleanup(0) at the end, as 
    // exiting the main thread should also cancel all running threads 
    exit_cleanup(0); 
} 

cleanUp() { 
    while (willExit != false); 
    for (all thread saved globally) { 
     cancel and join current thread; 
    } 
    exit(exitStatusCode); 
} 

main(args) { 
    mainThreadArgs = args; 
    create_thread(mainThreadId, mainThreadFunc); 
    cleanUp(); 
} 



Из приведенного выше кода, я не вижу никаких причин, почему Valgrind, или любой другой проверки утечки памяти, будет жаловаться для любых «все еще достижимых» или «возможно потерянных» утечек.

Любые исправления в моем решении оцениваются !!

0

Отсоединение потока с использованием pthread_detach() сообщает библиотеке pthreads, что ресурсы, связанные с этим потоком, могут быть освобождены после завершения потока. Тем не менее, вы покидаете весь процесс, и, следовательно, Valgrind жалуется на утечку ресурсов. Хотя, при выходе процесса все ресурсы будут очищены на современных операционных системах, Valgrind довольно придирчив.

Таким образом, вместо вызова exit() - который выходит весь процесс не только вызывающий поток, если вы звоните pthread_exit(NULL); или return NULL; от thread_func(), вы должны увидеть библиотеку Pthreads освобождает выделенные ресурсы.

pthread_join, вызванный из другой нити, перекрывается с pthread_detach из той же темы?

Вы не можете присоединиться к нити, которая была отсоединена (либо она была создана с установленным или отсоединенным атрибутом, либо с использованием pthread_detach()). Документация pthread_detach() говорит, что неопределенные:

Попытка отсоединять уже отделенные результаты нити в неустановленном поведения.

+0

Но, мое внимание здесь - это то, что если я хочу выйти из всей программы из бокового потока, а не только из текущего потока, не делая жалоб от valgrind (я знаю, что последняя очистка не была бы такой важной, но это было бы быть хорошим, чтобы очистить все при выходе из программы !!) ?? – falhumai

+0

Как правило, вы не хотите выходить из всего процесса из потока, так как он может внезапно прекратить все остальные потоки, не допуская никаких очищений. Фактически 'exit()' не многопоточно безопасен! Если вы хотите выйти из условия, вы можете настроить флаг (атомарно) в этом потоке и сообщить другим потокам, которые вы хотите закрыть (чтобы они могли выполнять ceanups), а затем один из потоков, например основной поток может выйти безопасно. – usr

 Смежные вопросы

  • Нет связанных вопросов^_^