I'm practicing with concurrency in C, and I seem to encounter some problems with semaphores. I'm using Xcode 6.3.2 in MacOSX.
Here it is a sample program that seems to act strangely: the purpose of the example is to print either ABCD or BACD strings
#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <errno.h>
void *thread1(void*);
void *thread2(void*);
sem_t *sem0, *sem1, *sem2;;
int main(int argc, const char * argv[]) {
pthread_t t1, t2;
sem0 = sem_open("sem0", O_CREAT, 0600, 2);
sem1 = sem_open("sem1", O_CREAT, 0600, 0);
sem2 = sem_open("sem2", O_CREAT, 0600, 0);
// quick check
if (sem0 == SEM_FAILED || sem1 == SEM_FAILED || sem2 == SEM_FAILED) {
printf("Something went wrong\n");
return 0;
}
pthread_create(&t1, NULL, thread1, NULL);
pthread_create(&t2, NULL, thread2, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
sem_close(sem0);
sem_close(sem1);
sem_close(sem2);
return 0;
}
void *thread1(void* arg) {
int n=0;
while (n<10) {
sem_wait(sem0);
printf("A");
fflush(stdout);
sem_wait(sem1);
printf("C");
fflush(stdout);
sem_post(sem2);
n++;
}
pthread_exit(NULL);
}
void *thread2(void* arg) {
int n=0;
while (n<10) {
sem_wait(sem0);
printf("B");
fflush(stdout);
sem_post(sem1);
sem_wait(sem2);
printf("D\n");
fflush(stdout);
sem_post(sem0);
sem_post(sem0);
n++;
}
pthread_exit(NULL);
}
If I implemented correctly the semaphores, the result would be either ABCD or BACD, but in reality I get a whole variety of strange output.
I will include part of that output here
ABCD
BAD
CABCD
BAD
CBAD
CBAD
CBAD
CBAD
CBAD
CBAD
C
Is someone able to help me? Thanks in advance
IMPORTANT EDIT: I downloaded Ubuntu, and the code is working smoothly there, no problems at all. So, to resume
Don't know why.
Your problem is probably that printf output is buffered and shared between threads. You'd have to ensure to empty the buffer with fflush before posting on the semaphores.
There's a typo when you call sem_open() for sem2 - the name passed in is "sem1":
sem1 = sem_open("sem1", O_CREAT, 0600, 0);
sem2 = sem_open("sem1", O_CREAT, 0600, 0);
// ^^^^
So the pointers sem1 and sem2 would be referring to the same semaphore.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With