So I know that you can create barriers in C to control the flow of a threaded program. You can initialize the barrier, have your threads use it, and then destroy it. However, I am unsure whether or not the same barrier can be reused (say if it were in a loop). Or must you use a new barrier for a second wait point? As an example, is the below code correct (reusing the same barrier)?
#include <pthread.h>
pthread_barrier_t barrier;
void* thread_func (void *not_used) {
//some code
pthread_barrier_wait(&barrier);
//some more code
pthread_barrier_wait(&barrier);
//even more code
}
int main() {
pthread_barrier_init (&barrier, NULL, 2);
pthread_t tid[2];
pthread_create (&tid[0], NULL, thread_func, NULL);
pthread_create (&tid[1], NULL, thread_func, NULL);
pthread_join(tid[0], NULL);
pthread_join(tid[1], NULL);
pthread_barrier_destroy(&barrier);
}
Yes, they are reusable. The man page says:
When the required number of threads have called pthread_barrier_wait()...the barrier shall be
reset to the state it had as a result of the most recent
pthread_barrier_init() function that referenced it.
Related
I have created two threads in c. I want to execute two separate functions by each threads. How to make one particular thread to be executed first.
#include <stdio.h>
#include <pthread.h>
void* function_1(void* p)
{
// statements
}
void* function_2(void* p)
{
// statements
}
int main(void)
{
pthread_t id1;
pthread_t id2;
pthread_create(&id1, NULL, function_1, NULL);
pthread_create(&id2, NULL, function_2, NULL);
pthread_exit(NULL);
}
How do I make function_1 to be executed before function_2 when the program starts?
Change your main function to look like this:
int main(void) {
function_1(NULL);
function_2(NULL);
}
No joke! If it's important for function_2() to not start until function_1() is finished, then that's how to do it. Any time you need a program to do certain things in a certain, strict order; the best way to achieve that is to do all of the things in the same thread.
Threads do need to "sync up" with each other from time to time (e.g., it doesn't make any sense for a consumer to take something out of a queue before a producer puts something in to the queue to be taken), but if your threads don't spend most of their time working independently of each other, then you probably aren't getting any benefit from using multiple threads.
#SolomonSlow has already stated the obvious. Why have several threads if you want sequential execution?
Bust just for completeness:
pthread_create(&id1, NULL, function_1, NULL);
pthread_join(id1, NULL);
pthread_create(&id2, NULL, function_2, NULL);
As stated in one of the other answers, your problem is likely an XY problem. It would probably be best to not use multithreading at all in such a situation, but use a single thread instead.
If you really do want to use threads, then, as already stated in one of the other answers, using pthread_join would probably be the best solution for the code you posted in your question.
However, if you merely want to ensure that the code in function_2 is not executed before another thread has finished executing function_1, and don't want to wait for the thread executing function_1 to terminate (e.g. because the thread is supposed to do something else after calling function_1), then I recommend that you synchronize the threads using a pthreads condition variable together with a pthreads mutex.
The following example adds code to the end of function_1 to signal the other thread that it may now proceed with function_2. It also adds code to the start of function_2 which waits for this signal to be sent.
Here is the example:
#include <stdio.h>
#include <pthread.h>
struct sync_data
{
pthread_mutex_t mutex;
volatile int predicate;
pthread_cond_t cond;
};
void* function_1(void* p)
{
// the function's main code goes here
//signal to other thread that it may now proceed
struct sync_data *psd = p;
pthread_mutex_lock( &psd->mutex );
psd->predicate = 1;
pthread_mutex_unlock( &psd->mutex );
pthread_cond_signal( &psd->cond );
}
void* function_2(void* p)
{
//wait for signal from other thread
struct sync_data *psd = p;
pthread_mutex_lock( &psd->mutex );
while ( !psd->predicate )
pthread_cond_wait( &psd->cond, &psd->mutex );
pthread_mutex_unlock( &psd->mutex );
// the function's main code goes here
}
int main(void)
{
struct sync_data sd;
pthread_t id1;
pthread_t id2;
//init sync_data struct members
pthread_mutex_init( &sd.mutex, NULL );
sd.predicate = 0;
pthread_cond_init( &sd.cond, NULL );
//create and start both threads
pthread_create( &id1, NULL, function_1, &sd );
pthread_create( &id2, NULL, function_2, &sd );
//wait for all threads to finish
pthread_join(id1, NULL);
pthread_join(id2, NULL);
//cleanup
pthread_mutex_destroy( &sd.mutex );
pthread_cond_destroy( &sd.cond );
}
I am running this in C++, however I think the same code would work in C. My understanding of a barrier is that when you pthread_barrier_init() you give it a number. That number represents how many threads must make a call to pthread_barrier_wait() before any of them get unblocked. So basically if the number is 4 and you have 3 threads who have executed that wait() line so far, all 3 of those threads will be blocked until a 4th thread comes along and calls pthread_barrier_wait().
I am trying to get all of the threads to begin execution at the same time.
#include <pthread.h>
#include <stdio.h>
void* thread_func(void* args) {
pthread_barrier_t *barrier = (pthread_barrier_t*)args;
printf("waiting for barrier\n");
pthread_barrier_wait(barrier);
printf("passed barrier\n");
return NULL;
}
int main() {
int const num_threads = 4;
pthread_t threads[num_threads];
pthread_barrier_t *barrier;
pthread_barrier_init(barrier, NULL, num_threads);
int i;
for (i = 0; i < num_threads; i++) {
pthread_create(&threads[i], NULL, thread_func, (void*)barrier);
}
for (i = 0; i < num_threads; i++) {
pthread_join(threads[i], NULL);
}
return 0;
}
output I receive:
waiting for barrier
waiting for barrier
waiting for barrier
passed barrier
passed barrier
passed barrier
waiting for barrier
passed barrier
output I expect:
waiting for barrier
waiting for barrier
waiting for barrier
waiting for barrier
passed barrier
passed barrier
passed barrier
passed barrier
Another very strange thing occurring is that in my pthread_barrier_init(barrier, NULL, num_threads) call, I can change the number to (num_threads+40) and the program still runs. I would think that in that case, all of the threads would be sitting at their wait() calls forever in that case since there would never be num_threads+40 threads waiting.
What am I missing?
pthread_barrier_t *barrier;
pthread_barrier_init(barrier, NULL, num_threads);
So barrier is a pointer that's never made to point to anything in particular. You never assign barrier a value, yet you pass its value to pthread_barrier_init. So pthread_barrier_init gets a garbage value, as do your threads.
Somewhere, you need to create an actual barrier, not just a pointer to one.
You could do this:
pthread_barrier_t actual_barrier;
pthread_barrier_t *barrier = &actual_barrier;
pthread_barrier_init(barrier, NULL, num_threads);
This actually does create a barrier and passes its address to pthread_barrier_init so the barrier you actually created can be initialized.
The answer #DavidSchwartz gave adds an extra line to make it clear how the pointer form would need to point to an actual instance of a pthread_barrier_t. However more typical for very localized usage would be:
pthread_barrier_t barrier;
pthread_barrier_init(&barrier, NULL, num_threads);
My command line tool keeps throwing the bus error: 10 message. Xcode debugger shows EXC_BAD_ACCESS message and highlights the function call that creates the thread. Manual debugging shows that the execution flow breaks at random positions inside the thread flow. I tried another compiler (gcc), but it ended up the same. Disabling pthread_mutex_lock() and pthread_mutex_unlock() doesn't help. I wrote this small example that reproduces the error.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
typedef struct thread_args {
pthread_mutex_t* mutex;
} thread_args;
void* test(void* t_args) {
printf("Thread initiated\n");
thread_args* args = (thread_args* )t_args;
printf("Args casted\n");
pthread_mutex_lock(args->mutex);
printf("Mutex locked\n");
pthread_mutex_unlock(args->mutex);
printf("Mutex unlocked\n");
pthread_exit(NULL);
}
int main() {
pthread_mutex_t mutex1;
pthread_mutex_init(&mutex1, NULL);
thread_args args;
args.mutex = &mutex1;
pthread_t* thread;
printf("Initiating a thread\n");
pthread_create(thread, NULL, test, &args);
return(0);
}
I think, in your case,
pthread_create(thread, NULL, test, &args);
at this call, thread is a pointer and not allocated memory. So, essentially pthread_create() tries to write into uninitialized memory, which creates undefined behavior.
Referring the man page of pthread_create()
Before returning, a successful call to pthread_create() stores the ID of the new thread in the buffer pointed to by thread;....
Instead, you can do
pthread_t thread;
...
pthread_create(&thread, NULL, test, &args);
You're using an uninitialized pointer to your pthread_t. The actual storage of the pthread_t needs to be somewhere!
Try :
int main() {
pthread_mutex_t mutex1;
pthread_mutex_init(&mutex1, NULL);
thread_args args;
args.mutex = &mutex1;
pthread_t thread;
printf("Initiating a thread\n");
pthread_create(&thread, NULL, test, &args);
return(0);
}
As other answers pointed out, you need to initialize your pointer thread which you can simply do with:
pthread_t thread;
pthread_create(&thread, NULL, test, &args);
Well, then I'll have to allocate memory dynamically, because different
threads are spawned inside many different functions, hence I can't use
local variables, because I'm not going to join the threads. Then, how
can I free the allocated memory without waiting for the thread to
finish, i.e. without calling join?
No. You don't need to dynamically allocate just because you are going to spawn multiple threads. The thread identifier is no longer needed once a thread has been created So whether it's a local variable or malloced is not important. It's only needed when you need to join or change some characteristics of the thread -- for which you need the ID. Otherwise, you can even reuse the same thread for creating multiple threads. For example,
pthread_t thread;
for( i = 0; i<8; i++)
pthread_create(&thread, NULL, thread_func, NULL);
is perfectly fine. A thread can always get its own ID by calling pthread_self() if needed. But you can't pass a local variable mutex1 to thread functions as once main thread exits, the mutex1 no longer exits as thread created continues to use it. So you either need malloc mutex1 or make it a global variable.
Another thing to do is that if you decide to let the main thread exit then you should call pthread_exit(). Otherwise, when the main thread exits (either by calling exit or simply return) then the whole process will die, meaning, all the threads will die too.
Hi I am trying to make 3 thread that will print different messages multiple times. Then sync them, so to print for example ONE TWO THREE ONE TWO THREE ONE TWO THREE... When I run the program sometimes it is not correct and I am not sure what I am doing wrong.
sem_t sema, semb, semc;
void *printone(void *arg)
{
printf("<ONE>");
sem_wait(&semc);
sem_post(&semb);
}
void *printtwo(void *arg)
{
printf("<TWO>");
sem_wait(&sema);
sem_post(&semc);
}
void *printthree(void *arg)
{
printf("<THREE>");
sem_wait(&semb);
sem_post(&sema);
}
main()
{
pthread_t th1,th2,th3;
int i;
sem_init(&sema,0,1);
sem_init(&semb,0,0);
sem_init(&semc,0,0);
for(i=0;i<10;i++){
pthread_create( &th1, NULL, printone, (void *) 1);
pthread_create( &th2, NULL, printtwo, (void *) 2);
pthread_create( &th3, NULL, printthree, (void *) 3);
pthread_join(th1, NULL);
pthread_join(th2, NULL);
pthread_join(th3, NULL);
}
pthread_exit(NULL);
}
You seem to have a workable approach: each thread waits on one semaphore, and later posts another to let the next thread run. For that to work, however, each thread should wait for its semaphore before performing its work (i.e. print its message).
Additionally, it looks like your thread functions are using the wrong semaphores. For printone() to run first, it must wait on the semaphore that you initialize with value 1. For printtwo() to run next, it must wait on whichever semaphore printone() posts to. Similarly, for printthree().
As a secondary matter, if your thread functions are not going to use their argument, then it would be best to pass NULL as the third argument to pthread_create().
I'm working on an application for Linux in C which uses multiple threads. The threads which are spawned by the main function do most of the work, and therefore usually finish last. I'm seeing some strange behavior, and I believe it's due to the main thread terminating before the spawned threads have a chance to finish their jobs. Here's some sample code to illustrate what I'm talking about:
#define _POSIX_C_SOURCE 200112L
#define _ISOC99_SOURCE
#define __EXTENSIONS__
#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>
void
my_cleanup(void *arg)
{
printf("cleanup: %s\n", (char *)arg);
}
void *
thread_stuff(void *arg)
{
printf("thread started\n");
pthread_cleanup_push(cleanup, "running");
if (arg)
pthread_exit((void *)2);
pthread_cleanup_pop(0);
pthread_exit((void *)2);
}
int
main()
{
int err;
pthread_t tid1, tid2;
err = pthread_create(&tid1, NULL, thread_stuff, (void *)1);
err = pthread_create(&tid2, NULL, thread_stuff, (void *)1);
sleep(10); /* change the value here if you want */
return SUCCESS;
}
When this code is run, the message from the cleanup function is printed twice, as it should be, but other times when it is run, I see the message printed only once sometimes, and other times I see it printed three times or not at all. You add in the sleep function in the main function to play with how long it takes the main function to terminate.
What can I do to make the program run as it should? I suspect it has something to do with joining to the children, but I don't entirely understand the concept of a join or how to apply it to this situation.
Thanks in advance!
Yes, you should "join" the threads. "Joining" a thread simply means waiting until the thread has terminated. In other words, you would do
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
to wait until both threads have terminated.
Edit: What to do if you have a child thread which, in turn, creates a "grandchild" thread? As a rule, whoever created the thread should wait for it to terminate ("join" it). So in this scenario, the child thread would call phtread_join on the grandchild thread, and the main thread would call join on the child thread.
I think you want to run pthread_join on each of the threads when your main thread completes -- this makes the main thread stop until the given thread finishes running. Other threads can still complete first though, so running pthread_join on every thread will prevent the main thread from terminiating until all of the others have terminated.
There is a definite problem if main() finishes before the threads it spawned if you don't call pthread_exit() explicitly. All of the threads it created will terminate because main() is done and no longer exists to support the threads.
By having main() explicitly call pthread_exit() as the last thing it does, main() will block and be kept alive to support the threads it created until they are done.
int main()
{
int err;
pthread_t tid1, tid2;
err = pthread_create(&tid1, NULL, thread_stuff, (void *)1);
err = pthread_create(&tid2, NULL, thread_stuff, (void *)1);
sleep(10); /* change the value here if you want */
/* Add the pthread_exit */
pthread_exit(NULL);
return SUCCESS;
}
Refer for more info here