Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C Semaphore strange precedence behavior

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

  • MacOSX 10.10.3 with Xcode 6.3.2 --> Not working properly
  • Ubuntu 15.04 --> Working properly

Don't know why.

like image 658
Ivano Avatar asked Nov 28 '25 11:11

Ivano


2 Answers

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.

like image 154
Jens Gustedt Avatar answered Dec 01 '25 02:12

Jens Gustedt


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.

like image 41
Michael Burr Avatar answered Dec 01 '25 03:12

Michael Burr