Do I Have to Pthread_Join Each Thread I Create

is it necessary to call pthread_join()

pthread_join does two things:

  1. Wait for the thread to finish.
  2. Clean up any resources associated with the thread.

If you exit the process without joining, then (2) will be done for you by the OS (although it won't do thread cancellation cleanup, just nuke the thread from orbit), and (1) will not. So whether you need to call pthread_join depends whether you need (1) to happen.

If you don't need the thread to run, then as everyone else is saying you may as well detach it. A detached thread cannot be joined (so you can't wait on its completion), but its resources are freed automatically if it does complete.

Do I have to pthread_join each thread I create?

You don't need to join a thread, but it is a good idea. Without calling pthread_join(), there is a possibility that the main() function will return before the thread terminates. In this case, pthread_join() makes the application wait until the other thread finishes processing. Plus, when you join the thread, it gives you the opportunity to check for return values and make sure that everything went smoothly, and it gives you the opportunity to clean up any resources you may have shared with the thread.

EDIT: A function that may be of interest to you is pthread_detach(). pthread_detach() allows the thread's storage to be cleaned up after the thread terminates, so there is no need to join the thread afterwards.

I want to program in parallel in C, should i avoid to use pthread_join()?

There are following issues.

  1. You need to have different pthread_t handles for different threads.
  2. Need different arg variables for different threads.
  3. You should call pthread_join() after creating all threads. pthread_join() will block the calling thread until the other thread exit. This will wait for that thread to exit.

.

pthread_t tClient[MAX_NUM_THREADS];
int arg[MAX_NUM_THREADS] = {0};

for (i = 0; i < nbClients; i++)
{
arg[i] = i+1; //Changed your for loop.
pthread_create(&(tClient[i]), NULL, procedureClient, (void*)&(arg[i]));
}

/* Other code. */

for (i = 0; i < nbClients; i++)
{
pthread_join(tClient[i], NULL); //Will wait for ith thread to exit.

free(clients[i].panier); //Libération de la mémoire pour chaque panier
}

is this execution parallel ? is it normal if my printf are in a
disorder ? (i think that this is normal but i prefer to ask)

Now the execution is parallel.
Prints in different threads may come in different order. It depends on which thread gets scheduled at what time.
You can synchronize the threads using mutex, semaphores, condition variables. etc.

How to make pthreads work concurrent without pthread_join()

The problem with your program, if you remove the pthread_join, is that main is returning and thereby causing the program to exit without doing anything to synchronize with the other thread and determine whether it's actually finished. When main returns, it's just as if you called exit, and the whole process terminates.

Aside from pthread_join there are lots of ways you could make main wait for other actions to be finished. You could wait on a semaphore that the other threads post, you could loop on a condition variable inspecting data other threads set, etc.

Alternatively you could have main call pthread_exit so to terminate the initial thread. Then the process will not exit until you call exit or until each thread has exited.

Does the main thread block when using the pthread_join function?

pthread_join() is fairly simple. Per its docs:

The pthread_join() function waits for the thread specified by
thread to terminate. If that thread has already terminated, then
pthread_join() returns immediately.

That is, yes, pthread_join() blocks the caller when that is necessary and appropriate. But it has no effect on any threads other than the caller's, not even the one being joined, and the number of currently-running threads is not directly relevant to pthread_join()s behavior.

You asked,

Does this mean that pthread_join executes the child thread, blocks the main thread, and executes the main thread when the child thread ends?

No.

Each successful call to pthread_create() starts a new thread that runs in parallel with all others in the process. If the system has multiple execution units, as most now do, then some of those parallel threads are likely to run concurrently on different execution units some of the time. No matter how many execution units are available, including if there is only one, the threads will share those execution units.

Scheduling execution time for threads is a function of the OS. No additional function calls are required to make it happen, and in particular, pthread_join() has nothing to do with making a thread run. Its job is to wait for the specified thread to finish running, and optionally to provide that thread's return value. That's all. And when it completes that task and returns, execution of the thread that performed the pthread_join() call continues normally, just as it would upon return from any other function call.

And you asked,

Can someone explain more clearly how pthread_join runs the child thread and the main thread?

pthread_join() does not do either of those things, except inasmuch as its return permits the thread that called it to proceed.

When one thread is blocked in pthread_join() that has no effect on the execution of other threads. All running, unblocked threads will execute in parallel, and perhaps concurrently, as already described. However many that is. That threads run in parallel is one of their key characteristics.

So yes, if the initial thread starts two others then attempts to join one of them, it is likely that the two additional threads will execute "crosswise". If you don't want that (at all) then you don't want threads. If you want to control that then that's one of the major functions of synchronization tools such as mutexes and condition variables.

Using pthread_join() on multiple threads giving unexpected behavior

The problem is that there is only one args structure. After pthread_create is called the new thread may not run immediately. By the time the threads run it is likely that they will both see the same args values. Calling pthread_join inside the thread creation loop "fixes" that because it ensures each thread finishes before args is updated to the next value.

To fix properly pass a different args to each thread. Illustrative code to do that:

struct arg_struct args[arg_num];
for(int i = 0; i < arg_num; i++){
args[i].fd = open(argv[i+1], O_RDONLY);
memcpy(args[i].name, argv[i+1], sizeof(args[i].name));
int thread_err = pthread_create(&threadid[i], NULL, count_bytes, &args[i]);
....


Related Topics



Leave a reply



Submit