Reputation: 293
I have just started learning threads and semaphores. I have created a simple program in C but its not working as expected. Please look at the code and tell me where I am wrong?
Thanks in advance.
I am using Ubuntu 14.04.
Commands I am using
gcc -o foo th.c -lpthread
./foo
th.c is the name of my c file
on execution every time the program should output:
Thread 1
Thread 2
Hello threads!
But I am getting most of the times
Thread 2
Thread 1
Code:
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
void myFun1(void *ptr);
void myFun2(void *ptr);
char buf[24];
sem_t mutex;
int main(){
pthread_t t1;
pthread_t t2;
char *msg1 = "Thread 1";
char *msg2 = "Thread 2";
sem_init(&mutex, 0, 1);
printf("mutex 00 %d \n", mutex);
pthread_create(&t1, NULL, (void *) &myFun1, (void *) msg1);
pthread_create(&t2, NULL, (void *) &myFun2, (void *) msg2);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
sem_destroy(&mutex);
return 0;
}
void myFun1 (void *ptr) {
char *msg = (char *)ptr;
printf("%s\n", msg);
sem_wait(&mutex);
sprintf(buf, "%s", "Hello Threads!");
sem_post(&mutex);
pthread_exit(0);
}
void myFun2(void *ptr) {
char *msg = (char *)ptr;
printf("%s\n", msg);
sem_wait(&mutex);
printf("%s\n", buf);
sem_post(&mutex);
pthread_exit(0);
}
Upvotes: 0
Views: 1169
Reputation: 239011
Your expectation is wrong. Your program does not include any synchronisation to make the t1
thread execute before the t2
thread (or vice-versa), so either ordering is possible.
In the case where t2
acquires the semaphore first, buf
will still be an empty string and that is what will print.
What you need is for t2
to wait until t1
has filled the buffer. You can do this by initialising the semaphore to 0, and only posting the semaphore after buf
has been written to. In main()
:
sem_init(&mutex, 0, 0);
In myFun1
:
void myFun1 (void *ptr) {
char *msg = (char *)ptr;
printf("%s\n", msg);
sprintf(buf, "%s", "Hello Threads!");
sem_post(&mutex);
pthread_exit(0);
}
In myFun2
:
void myFun2(void *ptr) {
char *msg = (char *)ptr;
printf("%s\n", msg);
sem_wait(&mutex);
printf("%s\n", buf);
pthread_exit(0);
}
Now t2
will only try to print buf
after it has been initialised, regardless of whether t2
or t1
runs first.
Upvotes: 1