is it necessary to call pthread_join()
pthread_join
does two things:
- Wait for the thread to finish.
- 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.
- You need to have different pthread_t handles for different threads.
- Need different arg variables for different threads.
- 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 bythread
to terminate. If that thread has already terminated, thenpthread_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
Finding The Longest Word in a Text File
Detecting If The Monitor Is Powered Off
How to Prevent Git from Committing Two Files with Names Differing Only in Case
How to Execute 'X86_64-Conda_Cos6-Linux-Gnu-Gcc': No Such File or Directory (Pysam Installation)
Why Strace Shows Eagain (Resource Temporarily Unavailable)
How to Install G++ on Centos Without Root
How to Change Core Pattern Only for a Particular Application
Can "Text File Busy" Happen When Two Processes Trying to Execute a Perl File in The Same Time
How to Get a Faster Output Pipe Than /Dev/Null
How to Set Errno in Linux Device Driver
Python3 No Such File or Directory
How to Set Environment Variable Within Gdb Using Shell Command
Changing File Permissions Linux