Stop main thread until all the other threads finishes - c

I want to stop the main thread until all the other threads finishes running. Is there any possible way to do that using pthreads in C ? Is there any possible way to sleep the main thread?
Here is the code I used to test.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
int a = 4;
void *func(void *arg)
{
for (int i = 0; i < 5; i++)
{
sleep(1);
printf("MY TURN : %d\n", i);
}
}
void *func_2(void *arg)
{
for (int i = 0; i < 5; i++)
{
sleep(1);
printf("YOUR TURN : %d\n", i);
}
}
void turn()
{
for (int i = 0; i < 5; i++)
{
sleep(1);
printf("THEIR TURN : %d \n", i);
}
}
int main()
{
pthread_t t_id, t_id_2;
pthread_create(&t_id, NULL, func, NULL);
pthread_create(&t_id_2, NULL, func_2, NULL);
turn();
pthread_join(t_id, NULL);
pthread_join(t_id_2, NULL);
}
Output of the code
THEIR TURN : 0
YOUR TURN : 0
MY TURN : 0
MY TURN : 1
THEIR TURN : 1
YOUR TURN : 1
MY TURN : 2
THEIR TURN : 2
YOUR TURN : 2
MY TURN : 3
THEIR TURN : 3
YOUR TURN : 3
MY TURN : 4
THEIR TURN : 4
YOUR TURN : 4
I want to run the turn() (function which is in main function) after running t_id and t_id_2 threads.

What you want is actually exactly what the pthread_join function does.
From man pthread_join:
int pthread_join(pthread_t thread, void **retval);
The pthread_join() function waits for the thread specified by <thread> to terminate.
If that thread has already terminated, then pthread_join() returns immediately.
The thread specified by <thread> must be joinable.
So in your main function you can just join the threads before calling turn:
pthread_t t_id, t_id_2;
pthread_create(&t_id, NULL, func, NULL);
pthread_create(&t_id_2, NULL, func_2, NULL);
pthread_join(t_id, NULL);
pthread_join(t_id_2, NULL);
turn();
return 0;
That way turn is called after the thread functions finish their work.

The classic way to wait for a thread is join() or pthread_join(), and that means the join caller must know all the thread ids, and the thread subroutines must return (terminate).
As thread pools and multiple pass problems came into vogue, non-terminal signalling like barrier() or pthread_barrier_init()/pthread_barrier_wait() became more common. The latter is a bit like a semaphore, with a thread count but also with one 'master' thread getting a unique return. In practice, barriers are often used in pairs, one for "are we all done this pass" with the unique 'master' thread delivering the result of the pass and another barrier to hold up the rest until the result is delivered by the 'master' thread before the problem pass variables can be modified in the next pass.

Related

Not able to create thread after reaching count 32751

#include <stdio.h>
#include <pthread.h>
#include <errno.h>
void *my_thread(void *ddd)
{
printf("Thread created\n");
pthread_exit(NULL);
}
int main()
{
int ret = 0, counter = 0;
pthread_t et;
while(1)
{
ret = pthread_create(&et, NULL, my_thread, (void *)&counter);
if(ret)
{
printf("Ret = %d, errr = %d, couter = %d\n", ret, errno, counter);
break;
}
counter++;
}
return 0;
}
Above is my C code. checked ulimit -s it gives 8192.I am not using pthred_join because i want to process my data parallel and any how thread will be exited after finishing its job.
output of the program after creating 32750 thred is
Thread created 32750
Thread created 32751
Ret = 11, errr = 12, couter = 32751
From the pthread_create man page:
A thread may either be joinable or detached.
...
Only when a terminated joinable thread has been joined are the last of its
resources released back to the system.
...
When a detached thread terminates, its resources are automatically released
back to the system:
....
By default, a new thread is created in a joinable state, unless attr was set
to create the thread in a detached state (using thread_attr_setdetachstate(3)).
This means that for any thread you create but do not join, some resources are still kept after it terminates.
After a certain number of threads you will run out of resources.
To avoid this, cou can call pthread_detach after creating the thread or use pthread_attr_setdetachstate Before you create it.

C multithread program behaviour explanation

int g_ant = 0;
void *writeloop(void *arg)
{
while(g_ant < 10)
{
g_ant++;
usleep(rand()%10);
printf("%d\n", g_ant);
}
exit(0);
}
int main(void)
{
pthread_t time;
pthread_create(&time, NULL, writeloop, NULL);
writeloop(NULL);
pthread_join(time, NUL);
return 0;
}
Hi! I have four questions which I believe goes under the category race condition...? :-)
I'm trying to figure out why the printf of g_ant, on my computer, starts on 2 and continues to 10 in 90% of the cases, with an occasional 1, 3->10 output. My guess is because of the usleep which may hinder thread1 long enough to let thread2 increment and printf before thread1 reaches printf.
Wouldn't this also mess up numbers from 2->10?
I'm also struggeling to understand pthread_join's function in this program. My understanding is that it's used to wait for a thread to complete. Is it waiting for the writeloop function started by pthread_create?
Is writeloop(null) considered second thread?
g_ant++;
isn't atomic operation, which can cause undefined behaviour. You should use
pthread_mutex_lock(&mutex);
and
pthread_mutex_unlock(&mutex);
the reason why it 90% times starts at 2 is because thread time enters the function, increments g_ant and sleeps itself. OS tends to take it away from CPU and put there another thread that is not asleep, in your case that is your main thread which again increments it by 1 runs usleep. Now g_ant has value 2, thread time resumes and prints 2 and increments it to 3. Main thread gets resumed and prints the 3 and again increments it, this keeps switching that's why you see numbers from 2 -> 10 most of the time.
Hopefully it is clear enough and should answer 2. question as well.
pthread_join makes sure that other threads finish their job before your main thread quits the program.
nope it is not considered a second thread, it runs the function on the main thread.
hope it helps.
The main thread is considered another thread. The following might help you understand what's going on before you add mutexes (assuming
you have to do that next). Usually, you don't exit() the whole process
from a thread - it would never be joined in the main thread.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int g_ant = 0;
void *writeloop(void *arg)
{
while(g_ant < 10)
{
g_ant++;
usleep( rand() % 10 );
printf("thread: %u global: %d\n", (unsigned int)pthread_self(), g_ant);
}
return NULL;
}
int main(void)
{
pthread_t t;
pthread_create(&t, NULL, writeloop, NULL);
writeloop(NULL);
pthread_join(t, NULL);
printf("Joined\n");
return 0;
}

Thread synchronizing with mutex

I have two threads. First one should write:
1
2
3
4
5
6
7
8
9
Second one should write:
am 1
am 2
am 3
am 4
am 5
am 6
am 7
am 8
am 9
This is my code:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
pthread_mutex_t mutex;
int firstCounter = 0;
int secondCounter = 0;
void *writeloop(void *arg) {
while(firstCounter < 10) {
pthread_mutex_lock(&mutex);
firstCounter++;
printf("%d\n", firstCounter);
pthread_mutex_unlock(&mutex);
}
exit(0);
}
void *readLoop(void *arg) {
while(secondCounter < 10) {
pthread_mutex_lock(&mutex);
secondCounter++;
printf("am %d\n", secondCounter);
pthread_mutex_unlock(&mutex);
}
exit(0);
}
int main(void)
{
pthread_t tid, fid;
pthread_mutex_init(&mutex, NULL);
pthread_create(&tid, NULL, writeloop, NULL);
pthread_create(&fid, NULL, readLoop, NULL);
pthread_join(tid, NULL);
pthread_join(fid, NULL);
pthread_mutex_destroy(&mutex);
return 0;
}
But its not working correctly. Sometimes the second method doesnt work, sometimes it works. Sometimes the first one work correctly, sometimes it prints:
1
2
3
4
5
6
7
Where is my mistake?
Better to use two different mutex variables to handle the two thread for read and write operation.
Since In current situation it fully depends upon the scheduling, if write thread gets schedule first then it acquire the mutex lock. So, later read thread has to wait for mutex lock until write thread released it and vice-versa.
As the commenter suggested, don't call exit() on the thread functions because that's used to terminate a process.
Might also be a good idea to call fflush(stdout) after each printf() as well to
ensure that the print buffer is flushed by the thread that last wrote to it.
Not sure why you're using a global variable in your while() loop. Probably better to use a for loop with a local variable.

Output in multi threading program

Writing my basic programs on multi threading and I m coming across several difficulties.
In the program below if I give sleep at position 1 then value of shared data being printed is always 10 while keeping sleep at position 2 the value of shared data is always 0.
Why this kind of output is coming ?
How to decide at which place we should give sleep.
Does this mean that if we are placing a sleep inside the mutex then the other thread is not being executed at all thus the shared data being 0.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include<unistd.h>
pthread_mutex_t lock;
int shared_data = 0;
void * function(void *arg)
{
int i ;
for(i =0; i < 10; i++)
{
pthread_mutex_lock(&lock);
shared_data++;
pthread_mutex_unlock(&lock);
}
pthread_exit(NULL);
}
int main()
{
pthread_t thread;
void * exit_status;
int i;
pthread_mutex_init(&lock, NULL);
i = pthread_create(&thread, NULL, function, NULL);
for(i =0; i < 10; i++)
{
sleep(1); //POSITION 1
pthread_mutex_lock(&lock);
//sleep(1); //POSITION 2
printf("Shared data value is %d\n", shared_data);
pthread_mutex_unlock(&lock);
}
pthread_join(thread, &exit_status);
pthread_mutex_destroy(&lock);
}
When you sleep before you lock the mutex, then you're giving the other thread plenty of time to change the value of the shared variable. That's why you're seeing a value of "10" with the 'sleep' in position #1.
When you grab the mutex first, you're able to lock it fast enough that you can print out the value before the other thread has a chance to modify it. The other thread sits and blocks on the pthread_mutex_lock() call until your main thread has finished sleeping and unlocked it. At that point, the second thread finally gets to run and alter the value. That's why you're seeing a value of "0" with the 'sleep' at position #2.
This is a classic case of a race condition. On a different machine, the same code might not display "0" with the sleep call at position #2. It's entirely possible that the second thread has the opportunity to alter the value of the variable once or twice before your main thread locks the mutex. A mutex can ensure that two threads don't access the same variable at the same time, but it doesn't have any control over the order in which the two threads access it.
I had a full explanation here but ended up deleting it. This is a basic synchronization problem and you should be able to trace and identify it before tackling anything more complicated.
But I'll give you a hint: It's only the sleep() in position 1 that matters; the other one inside the lock is irrelevant as long as it doesn't change the code outside the lock.

How can I wait for any/all pthreads to complete?

I just want my main thread to wait for any and all my (p)threads to complete before exiting.
The threads come and go a lot for different reasons, and I really don't want to keep track of all of them - I just want to know when they're all gone.
wait() does this for child processes, returning ECHILD when there are no children left, however wait does not (appear to work with) (p)threads.
I really don't want to go through the trouble of keeping a list of every single outstanding thread (as they come and go), then having to call pthread_join on each.
As there a quick-and-dirty way to do this?
Do you want your main thread to do anything in particular after all the threads have completed?
If not, you can have your main thread simply call pthread_exit() instead of returning (or calling exit()).
If main() returns it implicitly calls (or behaves as if it called) exit(), which will terminate the process. However, if main() calls pthread_exit() instead of returning, that implicit call to exit() doesn't occur and the process won't immediately end - it'll end when all threads have terminated.
http://pubs.opengroup.org/onlinepubs/007908799/xsh/pthread_exit.html
Can't get too much quick-n-dirtier.
Here's a small example program that will let you see the difference. Pass -DUSE_PTHREAD_EXIT to the compiler to see the process wait for all threads to finish. Compile without that macro defined to see the process stop threads in their tracks.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
static
void sleep(int ms)
{
struct timespec waittime;
waittime.tv_sec = (ms / 1000);
ms = ms % 1000;
waittime.tv_nsec = ms * 1000 * 1000;
nanosleep( &waittime, NULL);
}
void* threadfunc( void* c)
{
int id = (int) c;
int i = 0;
for (i = 0 ; i < 12; ++i) {
printf( "thread %d, iteration %d\n", id, i);
sleep(10);
}
return 0;
}
int main()
{
int i = 4;
for (; i; --i) {
pthread_t* tcb = malloc( sizeof(*tcb));
pthread_create( tcb, NULL, threadfunc, (void*) i);
}
sleep(40);
#ifdef USE_PTHREAD_EXIT
pthread_exit(0);
#endif
return 0;
}
The proper way is to keep track of all of your pthread_id's, but you asked for a quick and dirty way so here it is. Basically:
just keep a total count of running threads,
increment it in the main loop before calling pthread_create,
decrement the thread count as each thread finishes.
Then sleep at the end of the main process until the count returns to 0.
.
volatile int running_threads = 0;
pthread_mutex_t running_mutex = PTHREAD_MUTEX_INITIALIZER;
void * threadStart()
{
// do the thread work
pthread_mutex_lock(&running_mutex);
running_threads--;
pthread_mutex_unlock(&running_mutex);
}
int main()
{
for (i = 0; i < num_threads;i++)
{
pthread_mutex_lock(&running_mutex);
running_threads++;
pthread_mutex_unlock(&running_mutex);
// launch thread
}
while (running_threads > 0)
{
sleep(1);
}
}
If you don't want to keep track of your threads then you can detach the threads so you don't have to care about them, but in order to tell when they are finished you will have to go a bit further.
One trick would be to keep a list (linked list, array, whatever) of the threads' statuses. When a thread starts it sets its status in the array to something like THREAD_STATUS_RUNNING and just before it ends it updates its status to something like THREAD_STATUS_STOPPED. Then when you want to check if all threads have stopped you can just iterate over this array and check all the statuses.
Don't forget though that if you do something like this, you will need to control access to the array so that only one thread can access (read and write) it at a time, so you'll need to use a mutex on it.
you could keep a list all your thread ids and then do pthread_join on each one,
of course you will need a mutex to control access to the thread id list. you will
also need some kind of list that can be modified while being iterated on, maybe a std::set<pthread_t>?
int main() {
pthread_mutex_lock(&mutex);
void *data;
for(threadId in threadIdList) {
pthread_mutex_unlock(&mutex);
pthread_join(threadId, &data);
pthread_mutex_lock(&mutex);
}
printf("All threads completed.\n");
}
// called by any thread to create another
void CreateThread()
{
pthread_t id;
pthread_mutex_lock(&mutex);
pthread_create(&id, NULL, ThreadInit, &id); // pass the id so the thread can use it with to remove itself
threadIdList.add(id);
pthread_mutex_unlock(&mutex);
}
// called by each thread before it dies
void RemoveThread(pthread_t& id)
{
pthread_mutex_lock(&mutex);
threadIdList.remove(id);
pthread_mutex_unlock(&mutex);
}
Thanks all for the great answers! There has been a lot of talk about using memory barriers etc - so I figured I'd post an answer that properly showed them used for this.
#define NUM_THREADS 5
unsigned int thread_count;
void *threadfunc(void *arg) {
printf("Thread %p running\n",arg);
sleep(3);
printf("Thread %p exiting\n",arg);
__sync_fetch_and_sub(&thread_count,1);
return 0L;
}
int main() {
int i;
pthread_t thread[NUM_THREADS];
thread_count=NUM_THREADS;
for (i=0;i<NUM_THREADS;i++) {
pthread_create(&thread[i],0L,threadfunc,&thread[i]);
}
do {
__sync_synchronize();
} while (thread_count);
printf("All threads done\n");
}
Note that the __sync macros are "non-standard" GCC internal macros. LLVM supports these too - but if your using another compiler, you may have to do something different.
Another big thing to note is: Why would you burn an entire core, or waste "half" of a CPU spinning in a tight poll-loop just waiting for others to finish - when you could easily put it to work? The following mod uses the initial thread to run one of the workers, then wait for the others to complete:
thread_count=NUM_THREADS;
for (i=1;i<NUM_THREADS;i++) {
pthread_create(&thread[i],0L,threadfunc,&thread[i]);
}
threadfunc(&thread[0]);
do {
__sync_synchronize();
} while (thread_count);
printf("All threads done\n");
}
Note that we start creating the threads starting at "1" instead of "0", then directly run "thread 0" inline, waiting for all threads to complete after it's done. We pass &thread[0] to it for consistency (even though it's meaningless here), though in reality you'd probably pass your own variables/context.

Resources