0

I'm trying to create 2 threads and make them execute one after another, and I'm confused by the different result between adding or not a usleep() function call inside them.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<semaphore.h>

sem_t sem;

void *func1(void *arg){
    int i=0;
    sem_wait(&sem);

    for(i='A';i<='Z';i++){
        putchar(i);
        fflush(stdout);
        usleep(100); //100ms
    }

    sem_post(&sem);
    return NULL;
}

void *func2(void *arg){
    int i=0;
    sem_wait(&sem);

    for(i='a';i<='z';i++){
        putchar(i);
        fflush(stdout);
        usleep(100); //100ms
    }

    sem_post(&sem);
    return NULL;
}

int main(void){
    pthread_t tid1,tid2;
    sem_init(&sem,0,1);

    pthread_create(&tid1,NULL,func1,NULL);
    pthread_create(&tid2,NULL,func2,NULL);

    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);

    printf("\nmain exit...\n");

    sem_destroy(&sem);
    return 0;
}

so this gives a wired alternate execution result:

AabBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ

without usleep() calling, the result is expected:

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

I'm working with osxsdk 13, with gcc version 12.3.0.

UPDATE:

compiler warnings:

=> gcc sem.c
sem.c: In function 'main':
sem.c:149:5: warning: 'sem_init' is deprecated [-Wdeprecated-declarations]
  149 |     int flag  = sem_init(&sem,0,1);
      |     ^~~
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/usr/include/semaphore.h:29,
                 from sem.c:5:
/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/usr/include/sys/semaphore.h:55:5: note: declared here
   55 | int sem_init(sem_t *, int, unsigned int) __deprecated;
      |     ^~~~~~~~
sem.c:166:5: warning: 'sem_destroy' is deprecated [-Wdeprecated-declarations]
  166 |     sem_destroy(&sem);
      |     ^~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/usr/include/sys/semaphore.h:53:5: note: declared here
   53 | int sem_destroy(sem_t *) __deprecated;
      |     ^~~~~~~~~~~
akanesora
  • 81
  • 6
  • Can't replicate. Check if any of the sem_ calls are failing. – ikegami Jul 27 '23 at 21:51
  • 2
    I believe your calls to `sem_wait()` are failing, which means your threads' printing routines aren't serialized. Check the return values coming back from the sem_wait() calls. – Jeremy Friesner Jul 27 '23 at 21:53
  • 1
    Looks like the root of the problem is that `sem_init()` is failing, with perror() reporting "Function not implemented" afterwards. – Jeremy Friesner Jul 27 '23 at 21:56
  • @JeremyFriesner yes, exactly, can you explain it more detail? I'm not quiet sure what's going on here. I have added complete compiler time warnings. – akanesora Jul 27 '23 at 21:59
  • @akanesora It appears `sem_init()` has been deliberately broken on MacOS/X -- dunno why they allow it to compile only to have it fail and do nothing useful at runtime, but that seems to be the case. You'll need to use `sem_open()` instead; a fixed version of your example program is here: https://public.msli.com/lcs/jaf/test.c – Jeremy Friesner Jul 27 '23 at 22:05
  • @JeremyFriesner Perfect, thanks for you time, I would close this question as it had been marked duplicated, thanks again! – akanesora Jul 27 '23 at 22:09

0 Answers0