Question

I have the following code. the build application is myprogram.

If I launch myprogram and then killall myprogram and immediately after that I launch again myprogram then myprogram crash.

the crash cause is due to that the management thread created by the first launch is not properly cleared before the second launch.

so in the second launch whent myprogram try to create thread with the pthread and the old thread management is not removed yet so it causes a crash.

Are there a way to kill the management thread at the end of my first launch or at the beginning of my second launch with C?

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

pthread_t test_thread;

void *thread_test_run (void *v)
{
    int i=1;
    while(1)
    {
       printf("into thread %d\r\n",i);
       i++; 
       sleep(1);
    }
    return NULL
}

int main()
{
    // ps aux | grep myprogram  ---> show 1 myprogram (1 for the main application)

    pthread_create(&test_thread, NULL, &thread_test_run, NULL);

    // ps aux | grep myprogram  ---> show 3 myprogram
    // (1st for the main application)
    // (2nd for the management thread. thread which manage all created thread)
    // (3rd for the created thread)

    sleep (20);  


    pthread_cancel(test_thread);

    // ps aux | grep myprogram  ---> show 2 myprogram and
    // (1st for the main application)
    // (2nd for the management thread. thread which manage all created thread)

    sleep(100);
    // in this period (before the finish of myprogram)
    // I execute killall to kill myprogram 
    // and then immediately I re-launch myprogram and then the program crash
    // because the management thread is not immediately killed

}

BTW:

the linux use libuClibc-0.9.30.1.so and according to this question How to kill all subprocess created with pthread_create after cancelling a thread? this libc use linux thread implementation of pthread and does not use libc with NPTL ("Native posix thread library") implementation so the management thread will be created only for this case of libc.

Was it helpful?

Solution

I think you're having this problem because you're killing the thread manager by using killall according to The Native POSIX Thread Library for Linux paper from Redhat:

If the manager thread gets killed the remainder of the process is in a state which must be manually cleaned up.

And also Linux threading models compared:

A fatal signal is able to kill all the threads. The LinuxThreads design on this front has been consistent. Once a process receives a fatal signal, the thread manager kills all the other threads (processes) with the same signal.

Which means that if you kill the thread manager, it won't get a chance to kill the other threads, so you should only kill the main process using kill -p pid not killall

I think if the main process exists normally, or receives a signal, the thread manager will be killed too eventually when it's done killing and waiting on other threads, however, it also mentions that if you call pthread_exit all other processes will be killed before returning to main:

If the main process calls pthread_exit(), the process is not terminated. The main thread goes to sleep, and it is the job of the manager thread to wake up the main thread when all other threads have been killed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top