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.
Related
I have two threads a nurse thread and a client thread. The nurse thread is supposed to wait until the client thread is read in order to to vaccinate the client. The client waits until the nurse completes the vaccine. I keep getting this error no matter what I do. I am not sure how to fix it. The indexes are all indexes of nurses, so they should be in the array.
sem_t* vacc_completed[NUM_NURSES];
sem_t* ready_clients[NUM_NURSES];
Client Thread
sem_post(ready_clients[new_station]);
//wait for the nurse to complete the vaccination
sem_wait(vacc_completed[new_station]);
Nurse Thread
sem_wait(ready_clients[id]);
//give the client a vaccination (which takes 5 seconds to administer)
fprintf(stderr, "%s: nurse %ld is administering the vaccine\n", curr_time_s(), id);
//administer();
sem_post(vacc_completed[id]);
Main Intializing of threads
srand(time(0));
pthread_t nid[NUM_NURSES],cid[NUM_CLIENTS];
sem_init(&vials_sem,0, NUM_NURSES);
sem_init(®istration_sem,0 , NUM_REGISTRATIONS_SIMULTANEOUSLY);
sem_init(&station_full,0,0);
sem_init(&mutex,0,1);
//creation of nurse threads
for(long int i = 0; i < NUM_NURSES; ++i) {
sem_t n_ready;
sem_t c_ready;
sem_init(&n_ready, 0,0);
sem_init(&c_ready, 0,0);
vacc_completed[i]= &n_ready;
ready_clients[i] = &c_ready;
pthread_create(&nid[i], NULL, (void *)nurse,(void *)i);
}
//creation of client threads
for(long int i = 0; i <NUM_CLIENTS; ++i) {
pthread_create(&cid[i], NULL, (void *)client, (void *)i);
}
for(int i = 0; i < NUM_NURSES; ++i) {
pthread_join(nid[i], NULL);
}
for(int i = 0; i < NUM_CLIENTS; ++i) {
pthread_join(cid[i], NULL);
}
pthread_exit(0);
I am trying to wait for all the threads to terminate before the main() process terminates. Here is what I have so far:
void* mapperFunction()
{
printf("Hello\n");
return NULL;
}
int main()
{
int i; // Used in "for" loops.
int N = 3;
pthread_t* mapperThreads = (pthread_t*) malloc(sizeof(pthread_t) * N);
for ( i = 0; i < N; i++)
{ // Creates all the mapper threads.
pthread_create( &mapperThreads[N], NULL, mapperFunction, NULL);
}
for ( i = 0; i < N; i++)
{ // Waits for all the mapper threads to terminate.
pthread_join( mapperThreads[N],NULL);
}
return 0;
}
I get three different outputs when I run this code;
1- Hello\n
2- Helle\nHello\n
3- Hello\nHello\nHello\n
It looks like the main() process does not always wait for all threads to terminate. What am I doing wrong?
You want &mapperThreads[i] instead of &mapperThreads[N] in each case.
Maybe pthread_barrier_wait is what you're looking for ?
Link
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.
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
}
I'm trying to write a multi-threaded program, the number of threads based on command-line input, and so I can't hard-code pre-declared threads. Is this a valid way of doing it?
int threads = 5; // (dynamic, not hard-coded)
int i = 0;
pthread_t * thread = malloc(sizeof(pthread_t)*threads);
for (i = 0; i < threads; i++) {
pthread_t foobar;
thread[i] = foobar; // will this cause a conflict?
}
for (i = 0; i < threads; i++) {
int ret = pthread_create(&thread[i], NULL, (void *)&foobar_function, NULL);
if(ret != 0) {
printf ("Create pthread error!\n");
exit (1);
}
}
Here's my result from modifications suggested below. Seems to work just fine.
int threads = 5;
int i;
pthread_t * thread = malloc(sizeof(pthread_t)*threads);
for (i = 0; i < threads; i++) {
int ret = pthread_create(&thread[i], NULL, &foobar_function, NULL);
if(ret != 0) {
printf ("Create pthread error!\n");
exit (1);
}
// pthread_join(thread[i], NULL); // don't actually want this here :)
}
sleep(1); // main() will probably finish before your threads do,
free(thread); // so we'll sleep for illustrative purposes
What's in the first cycle? Does it set the array elements to uninitialized value?
So i think that's what you need:
int threads = 5, i = 0, ret = -1;
pthread_t * thread = malloc(sizeof(pthread_t)*threads);
for (i = 0; i < threads; i++) {
ret = pthread_create(&thread[i], NULL, &foobar_function, NULL);
if(ret != 0) {
printf ("Create pthread error!\n");
exit (1);
}
}
It spawns threads threads, starting foobar_function in each. And you have (if everything goes well:)) their ids in thread array. So for example you can cancel second thread by calling pthread_cancel(thread[1]) etc.
The first for loop is not valid C, and I'm not sure what you want it to do. Just remove it and the rest of the code looks ok, aside from the incorrect cast on foobar_function. The cast should be:
(void *(*)(void *))foobar_function
but unless the type is already this, or something very close, your program probably has undefined behavior. It would be better to fix the function signature so no cast is needed.
If you're trying to write a multithreaded program, but don't understand how to allocate a dynamically sized data structure, you may be doing things wrong.
Learn to walk before you run.
Consider using an easier language, and avoiding the use of (explicit) threads.
Threads are very difficult to use correctly; dynamically sized arrays are very easy to achieve (even fairly easy in C)