How to make main thread wait for all child threads finish? - c

I intend to fire 2 threads in the main thread, and the main thread should wait till all the 2 child threads finish, this is how I do it.
void *routine(void *arg)
{
sleep(3);
}
int main()
{
for (int i = 0; i < 2; i++) {
pthread_t tid;
pthread_create(&tid, NULL, routine, NULL);
pthread_join(&tid, NULL); //This function will block main thread, right?
}
}
In the above code, pthread_join indeed makes main thread wait for the child threads, but the problem is, the second thread won't be created untill the first one finishes. This is not what I want.
What I want is, the 2 threads get created immediatly in the main thread, and then main thread waits for them to finish. Seems like pthread_join cannot do the trick, can it?
I thought, maybe via a semaphore I can do the job, but any other way?

int main()
{
pthread_t tid[2];
for (int i = 0; i < 2; i++) {
pthread_create(&tid[i], NULL, routine, NULL);
}
for (int i = 0; i < 2; i++)
pthread_join(tid[i], NULL);
return 0;
}

First create all the threads, then join all of them:
pthread_t tid[2];
/// create all threads
for (int i = 0; i < 2; i++) {
pthread_create(&tid[i], NULL, routine, NULL);
}
/// wait all threads by joining them
for (int i = 0; i < 2; i++) {
pthread_join(tid[i], NULL);
}
Alternatively, have some pthread_attr_t variable, use pthread_attr_init(3) then pthread_attr_setdetachedstate(3)
on it, then pass its address to pthread_create(3) second argument. Thos would create the threads in detached state. Or use pthread_detach as explained in Jxh's answer.
Remember to read some good Pthread tutorial. You may want to use mutexes and condition variables.
You could use frameworks wrapping them, e.g. Qt or POCO (in C++), or read a good C++ book and use C++ threads.
Conceptually, threads have each their call stack and are related to continuations. They are "heavy".
Consider some agent-oriented programming approach: as a rule of thumb, you don't want to have a lot of threads (e.g. 20 threads on a 10 core processor is reasonable, 200 threads won't be unless a lot of them are sleeping or waiting) and and do want threads to synchronize using mutex and condition variables and communicate and/or synchronize with other threads quite often (several times per second). See also poll(2), fifo(7), unix(7), sem_overview(7) with shm_overview(7) as another way of communicating between threads. In general, avoid using signal(7) with threads (read signal-safety(7)...), and use dlopen(3) with caution (probably only in the main thread).
A pragmatical approach would be to have most of your threads running some event loop (using poll(2), pselect(2), perhaps eventfd(2), signalfd(2), ....), perhaps communicating using pipe(7) or unix(7) sockets. See also socket(7).
Don't forget to document (on paper) the communication protocols between threads. For a theoretical approach, read books about π-calculus and be aware of Rice's theorem : debugging concurrent programs is difficult.

You could start the threads detached, and not worry about joining.
for (int i = 0; i < 2; i++) {
pthread_t tid;
pthread_create(&tid, NULL, routine, NULL);
pthread_detach(tid);
}
pthread_exit(0);
Or, alternatively, you can have the thread that dies report back to the main thread who it is, so that the threads are joined in the order they exited, rather than in the order you created them in.
void *routine(void *arg)
{
int *fds = (int *)arg;
pthread_t t = pthread_self();
usleep((rand()/(1.0 + RAND_MAX)) * 1000000);
write(fds[1], &t, sizeof(t));
}
int main()
{
int fds[2];
srand(time(0));
pipe(fds);
for (int i = 0; i < 2; i++) {
pthread_t tid;
pthread_create(&tid, NULL, routine, fds);
printf("created: %llu\n", (unsigned long long)tid);
}
for (int i = 0; i < 2; i++) {
pthread_t tid;
read(fds[0], &tid, sizeof(tid));
printf("joining: %llu\n", (unsigned long long)tid);
pthread_join(tid, 0);
}
pthread_exit(0);
}

#include<stdio.h>
#include<pthread.h>
int icnt = 0; //in non_bss data segment
pthread_mutex_t lock; //lock variable created stored into bss data segment
void *Thread_count(void* args) //syncronization
{
pthread_mutex_lock(&lock); //lock aquire
icnt++;
for(int x = 1; x <= icnt; x++)
{
printf("Hello from Thread_count : %d \n",icnt);
}
printf("\n");
pthread_mutex_unlock(&lock); //release lock
pthread_exit(NULL); //exit from child thread
}
int main()
{
pthread_t threads[4]; //created array of {unsigned long int}
int status = 0;
//creating threads in loop
for(int i = 1; i <= sizeof(threads)/sizeof(threads[0]); i++)
{
pthread_create(&threads[i], NULL, &Thread_count, NULL);
}
//waiting for threads in loop
for(int j = 1; j <= sizeof(threads)/sizeof(threads[0]); j++)
{
pthread_join(threads[j], &status);
printf("Thread number : %d <--> Thread status : %d\n",j, status);
}
pthread_exit(0); //end of main thread
}

Related

How to make all threads (pthread) wait till rest of all other threads are running before starting its execution?

The main processes launches 4 threads. Now at this time all 4 threads will start execution immediately, but I want all the threads to wait till rest of all threads are also in running state.
I remember using a semaphore to track the thread counts, but not able to recall it.
Is there any simple way to do without doing any busy-wait?
void *thread_routine(void *arg)
{
// this thread should wait here till rest of all threads are also ready to run
// do some job here
return NULL;
}
int main(int argc, char *argv[])
{
int i = 0;
pthread_t thid[4];
for (i = 0; i < 4; i++) {
pthread_create(&tid[i], NULL, thread_routine, NULL);
}
for (i = 0; i < 4; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}
What you describe sounds like barrier synchronization which can be implemented using pthread_barrier_wait.
Here's a simple example using it (from TLPI book).

Ending pthreads with deferred cancelation

I'm new to pthreads and signal handling and I am working on a project that will create x amount of pthreads as either a producer or consumer, that execute forever, and I want to end all threads and then the main in a systematic way.
To do this, I am attempting to catch the ^c with a signal handler and then setting some global flag to then end the threads.
I have tried doing the following but I am unsure if it is working or not and I would like advice on my thought process and implementation.
Here is what I am working with, omitting error checking:
#include stdio, pthread, stdlib, semaphore, time, string, unistd, signal
sem_t empty, full;
pthread_mutex_t mutex;
int flag = 0;
void *producer();
void *consumer();
void sig_handler(int sig);
int main(int argc, char *argv[]){
signal(handler(SIGINT, sig_handler);
//init locks and semas
pthread_mutex_init(&mutex, NULL);
sem_init(&empty, 0, SOME_BUFFER_SIZE);
sem_init(&full, 0, 0);
pthread_t prod_threads[5]; //5 for example, can be any amount passed in
pthread_t cons_threads[3];
//start up threads
for(i = 0; i < 5; i++)
pthread_create(&prod_threads[i], NULL, producer, NULL)
for(i = 0; i < 3; i++)
pthread_create(&cons_threads[i], NULL, consumer, NULL)
//join threads at end
for(i = 0; i < PROD; i++)
pthread_join(&prod_threads[i], NULL);
for(i = 0; i < CONS; i++)
pthread_join(&cons_threads[i], NULL);
sleep(4);//could be any amount of time
exit(EXIT_SUCCESS);
}
//not sure if I am going about this the right way
void sig_handler(int sig){
if(sig == SIGINT)
flag = 1;
}
void *producer(){
while(1){
sleep(x);//where x is some random time
//part I am concerned about:
if(flag)
exit(EXIT_SUCCESS);
//get locks and semaphore stuff
//enter crit section
//release locks, semaphore
}
void *consumer(){
while(1){
sleep(x);//sleep some random time
//again not sure if this is right or not
if(flag)
exit(EXIT_SUCCESS);
//get locks
//enter crit
//release locks
}
}
}
My program seems to execute properly, I'm just not sure if I am using pthreads and signals correctly and would like some guidance there. If you need more complete code just let me know
Thanks
You're execution seems appropriate, however using the docs #yano provided, you're pthread_join() is off ever so slightly.
Instead of:
for(i = 0; i < PROD; i++)
pthread_join(&prod_threads[i], NULL);
for(i = 0; i < CONS; i++)
pthread_join(&cons_threads[i], NULL);
You need:
for(i = 0; i < PROD; i++)
pthread_join(prod_threads[i], NULL);
for(i = 0; i < CONS; i++)
pthread_join(cons_threads[i], NULL);
Notice the ampersand. Whether or not this is what you are looking for, I am not sure, but I hope it helps.
I want to end all threads and then the main in a systematic way.
As Martin James suggests, post a special thread message into the queue telling the worker threads to terminate. This message should not be removed from the queue, so that all worker threads have a chance to receive it and terminate.
The other point is that you should not call exit in your worker threads, since this function terminates the entire process, defeating your original goal. Just return from the thread function.
Another point is that in a multi-threaded application it is good practice to handle all signals in one specific thread (often the main thread is the best candidate for that). And block the signals you expect to receive in all other threads. It should be done by blocking the expected signals before creating other threads, so that they inherit the signal mask, and eventually unblocking these signals in the signal handling thread when it is ready to handle them (e.g. when all extra threads have been created). This is because a signal targeted for a process (such as SIGINT) can be delivered to any one of its threads, but we want it to be handled by one specific thread. See Signal Generation and Delivery for more details.

two threads, first adds second substracts

This is a classic example of mutex locks. I don't know why the following code doesn't work, ie. it doesn't print "ctr = 0" every time (but, for example, ctr = 535).
int ctr;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
void * add (void * arg_wsk)
{
int i;
for (i = 0; i < 100000; i++) {
pthread_mutex_lock (&m);
ctr++;
pthread_mutex_unlock (&m);
}
return(NULL);
}
void * sub(void * arg_wsk)
{
int i;
for (i = 0; i < 100000; i++) {
pthread_mutex_lock (&m);
ctr--;
pthread_mutex_unlock (&m);
}
return(NULL);
}
int main()
{
pthread_t tid1, tid2;
int i;
void *res;
ctr = 0;
pthread_mutex_init(&m, NULL);
pthread_create(&tid1, NULL, add, NULL);
pthread_detach(tid1);
pthread_create(&tid2, NULL, sub, NULL);
pthread_detach(tid2);
pthread_join(tid1, &res);
pthread_join(tid2, &res);
pthread_mutex_destroy(&m);
printf("ctr = %d", ctr);
pthread_exit(NULL);
}
I think you are misusing the POSIX API. If you detach the threads, you shouldn't join them. Remove the detach and see if this improves things. I think you'll see that main() now blocks until the threads have completed.
Note also, from the link for the join call
ESRCH No thread could be found corresponding to that specified by the
given thread ID.
If you're lucky, you'll hit this. If you're not lucky, crazy things will happen. Don't mix detach and join calls on the same thread.
https://computing.llnl.gov/tutorials/pthreads/#Joining
The value of your counter ctr depends on both the threads completing their full execution.
According to pthread_detach(3)
Once a thread has been detached, it can't be joined with
pthread_join(3) or be made joinable again.
If you remove pthread_detach call from your program, you will get the expected output.
Also, consider explicitly creating your thread joinable(or detached) for portability.

pthreads program doesn't behave well

I'm trying to make a simple program using pthreads, want to make 6 threads and pass index to all of them. here's the code:
#include <pthread.h>
#include <stdio.h>
#define num_students 6
void thread_starter();
int main() {
pthread_t thread1[num_students];
int i = 0;
for(i = 0; i<num_students; i++) {
int q = i;
pthread_create(&thread1[i], NULL, (void *) &thread_starter, (void *)&q);
}
sleep(1);
}
void thread_starter(void* a) {
printf("Thread %i \n", *((int*)a));
}
And the output:
Thread 2
Thread 3
Thread 2
Thread 4
Thread 5
Thread 5
why do they have commmon names? what's wrong?
Thanks
You're passing a stack address from the main thread into all the child threads. There is no guarantee when these threads will be scheduled so you have no way of knowing whether the main thread will have updated its stack variable by the time each child gets around to reading it.
To avoid this, you need to allocate memory for the data being passed to each thread.
The easiest way to do this in your example is to use another automatic variable to store the data being passed to the new threads
void thread_starter(void* a);
int main() {
pthread_t thread1[num_students];
int thread_data[num_students];
int i = 0;
for(i = 0; i<num_students; i++) {
thread_data[i] = i;
pthread_create(&thread1[i], NULL, thread_starter, &thread_data[i]);
}
sleep(1);
}
Note also that you can avoid having to cast thread_starter if you give it the correct signature in your forward declaration.
For more complex programs you may need to dynamically allocate memory for each thread instead, passing ownership of that memory to the new threads.
int main() {
pthread_t thread1[num_students];
int i = 0;
for(i = 0; i<num_students; i++) {
int* data = malloc(sizeof(*data));
*data = i;
pthread_create(&thread1[i], NULL, thread_starter, data);
}
sleep(1);
}
void thread_starter(void* a) {
printf("Thread %i \n", *((int*)a));
free(a);
}
Finally, using sleep(1) isn't a very rigorous way of ensuring that all your threads will be run. It'd be better to use pthread_join instead
for(i = 0; i<num_students; i++) {
pthread_join(thread1[i], NULL);
}
sleep is not the correct tool to wait for spawned threads, use pthread_join for this.
Your main function terminating is equivalent to calling exit for the whole program and killing all the other threads.
Try This for Variation
void thread_starter(void* a) {
// Put a sleep(1) Here and see you will get even bizarre results
printf("Thread %i \n", *((int*)a));
}
Ok the problem here is of course
the race condition at this point here
int q = i;
pthread_create(&thread1[i], NULL, (void *) &thread_starter, (void *)&q);
lets say the first thread is created and the value at q is 0
now assume that before executing the statement Here
printf("Thread %i \n", *((int*)a));
if the main thread loops further and executes this statement here
int q = i;
again, then the q value changes (because its a reference) hence the problem
well one way to avoid this is to copy this reference variable in a local variable in thread routine also use mutex.
Sorry I was on a Hurry some more tips from my side
#define num_students 6
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // A Global Mutex
Will aquire a lock Here
pthread_mutex_lock( &mutex );
printf("\n Got Mutex %d\n", i);
int q = i;
pthread_create(&thread1[i], NULL, (void *) &thread_starter, (void *)&q);
and will release the lock Here in child Routine
int i = *((int*)a);
sleep(1);
pthread_mutex_unlock( &mutex );
printf("Thread %i \n", i);
P.S - Remove un necessary Prints and Sleeps where ever not applicable

Rejoining threads in C

In my main function, I spawn j threads which all compute the same task in parallel -- and then I want to wait for them to finish before exiting.
int main(...) {
// ...
int threads = 6;
pthread_t* thread = malloc(sizeof(pthread_t)*threads);
for(i = 0; i < threads; i++) {
struct thread_param *tp;
tp = malloc(sizeof(*tp));
// ...
int ret = pthread_create(&thread[i], NULL, &control, (void*)tp);
if(ret != 0) {
printf ("Create pthread error!\n");
exit (1);
}
}
for (j = 0; j < threads; j++) {
printf("JOINING THREAD: %i\n", j);
pthread_join( &thread[j], NULL);
}
exit(0);
}
However, nothing waits. Main just exits without ever completing the threaded tasks. Am I missing something?
hey, try pthread_join( thread[j], NULL); i think the problem is with types. I checked docs:
int pthread_join(pthread_t thread, void **value_ptr);
and thread is p_thread*, and thread[j] is p_thread, while &thread[j] is p_thread*, which is invalid. There just might internal error happen.
Edit: Yeah, I am very positive with that, pthread_t is basically int, so pthread_t* is accepted, it is just invalid thread handle, so pthread_join fails internally.

Resources