I am writing a multithreaded program. The introduction to pthread_join in the linux manual is:
The pthread_join() function waits for the thread specified by thread to terminate
.
I'm curious if this sentence means that the main thread and the child thread run separately, but when the child thread ends, the main thread can end.
Child1 thread: 0
Child1 thread: 1
...
Child1 thread: 9999
Parent thread: 0
...
Parent thread: 99
The result is always that after the child thread ends, the for loop behind the main thread will be executed. Does this mean that pthread_join
executes the child thread, blocks the main thread, and executes the main thread when the child thread ends?
But when I delete the comments of the following code, that is, create two child-threads, the expected phenomenon does not occur. child-thread 1 and child-thread 2 run crosswise. When the child thread 1 and the child thread 2 are finished, the for loop after the main thread pthread_join
starts to run.
Can someone explain more clearly how pthread_join
runs the child thread and the main thread?
#define _GNU_SOURCE
#include<stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sched.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <pthread.h>
#include "../utils/memory_utils.h"
#include "../utils/cache_utils.h"
#include "../utils/misc_utils.h"
void function(char *str){
for(int i=0;i<10000;i ){
printf("%s thread: %d\n", str, i);
}
}
int main(){
char *str = "string";
pthread_t start,start_2;
if (pthread_create(&start, NULL, (void *)function, "Child1") != 0) {
perror("pthread_create: trojan");
}
// if (pthread_create(&start_2, NULL, (void *)function, "Child2") != 0) {
// perror("pthread_create: trojan");
// }
pthread_join(start, NULL);
// pthread_join(start_2, NULL);
for(int i=0;i<100;i ){
printf("Parent thread: %d\n", i);
}
return 0;
}
CodePudding user response:
In your code, the main thread is blocked by the pthread_join()
function.
The pthread_join()
function waits for the thread specified by thread to terminate. In your case, the main thread is waiting for the child thread to terminate.
When you delete the comments of the code, that is, create two child-threads, the expected phenomenon does not occur. child-thread 1 and child-thread 2 run crosswise. When the child thread 1 and the child thread 2 are finished, the for loop after the main thread pthread_join()
starts to run.
Can someone explain more clearly how pthread_join runs the child thread and the main thread?
The pthread_join()
function waits for the specified thread to finish before it continues. In your case, when you comment out the second child thread, the main thread is blocked by the first child thread. When the first child thread finishes, the main thread continues and the for loop is executed.
However, when you create two child threads, the main thread is not blocked by the child threads because the pthread_join()
function returns immediately when it is called. The main thread will continue and the for loop will be executed.
CodePudding user response:
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.