Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reusing pthread_t variable for currently running threads

Tags:

c

pthreads

I'm abit uncertain if the following code will lead to undefined behavior.

//global
pthread_t thread1;

void *worker(void *arg){
  //do stuff
}


void spawnThread(){
  //init stuff
  int iret1 = pthread_create( &thread1, NULL, worker, (void*) p);
}

My spawnThread will make a new thread using the global thread1.

If I'm currently running a thread that is not finished, will I somehow cause undefined behaviour when starting a new thread using the thread1 variable?

If this is a problem, would it make sense to make my pthread_t variable local to a function? I think it might be problem because it will use the stack, and as soon as i return from my function that will be removed.

If I make my pthread_t local to a function, I can't use the pthread_join in a another part of my program. Is the canonical solution, to have a mutex'ed counter keeping track of how many current threads are running?

thanks

like image 422
monkeyking Avatar asked Jun 24 '11 11:06

monkeyking


3 Answers

The pthread_t is just an identifier. You can copy it round or destroy it at will. Of course, as you mention, if you destroy it (because it is local) then you cannot use it to call pthread_join.

If you reuse the same pthread_t variable for multiple threads then unless there is only one thread active at a time you are overwriting the older values with the new ones, and you will only be able to call pthread_join on the most recently started thread. Also, if you are starting your threads from inside multiple threads then you will need to protect the pthread_t variable with a mutex.

If you need to wait for your thread to finish, give it its own pthread_t variable, and call pthread_join at the point where you need to wait. If you do not need to wait for your thread to finish, call pthread_detach() after creation, or use the creation attributes to start the thread detached.

like image 50
Anthony Williams Avatar answered Oct 14 '22 03:10

Anthony Williams


pthread_t is just an identifier, and you can do whatever you like with it. Thread state is maintained internally in the C library (in the case of Glibc/NPTL, on an internal struct thread on Thread Local Storage, accessed on x86 via the GS register).

like image 39
ninjalj Avatar answered Oct 14 '22 03:10

ninjalj


Problem is, your thread1 variable is the only way to refer to your first thread.

The solution I often use is having an array of pthread_t where to store the thread ids I need to refer to. In this example it's a static array, but you can also use dynamically alloced memory.

static pthread_t running_threads[MAX_THREAD_RUNNING_LIMIT];
static unsigned int running_thread_count = 0;

// each time you create a new thread:
pthread_create( &running_threads[running_thread_count], blabla...);
running_thread_count++;

// don't forget to check running_thread_count against the size 
// of your running thread size MAX_THREAD_RUNNING_LIMIT

When you need to join() them, simply do it in a loop:

for(i =0; i<running_thread_count; i++)
{
    pthread_join(&running_threads[i], &return_value);
}
like image 36
Gui13 Avatar answered Oct 14 '22 03:10

Gui13