0

I am trying to create a semaphore and practicing by using this simple program, though I am getting a bunch of deprecated warnings when compiling on macos. I have been looking and having trouble finding a solution to get the semaphore to work for macos.

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

#define THREAD_NUM 4

sem_t semaphore;

void* routine(void* args) {
    sem_wait(&semaphore);
    sleep(1);
    printf("Hello from thread %d\n", *(int*)args);
    sem_post(&semaphore);
    free(args);
}

int main(int argc, char *argv[]) {
    pthread_t th[THREAD_NUM];
    sem_init(&semaphore, 0, 1);
    int i;
    for (i = 0; i < THREAD_NUM; i++) {
        int* a = malloc(sizeof(int));
        *a = i;
        if (pthread_create(&th[i], NULL, &routine, a) != 0) {
            perror("Failed to create thread");
        }
    }

    for (i = 0; i < THREAD_NUM; i++) {
        if (pthread_join(th[i], NULL) != 0) {
            perror("Failed to join thread");
        }
    }
    sem_destroy(&semaphore);
    return 0;
}

I am expecting the threads to be created for the routine function where 4 threads exist for 4 void* routine(). It should printf("Hello from thread") every second starting from thread 0 and going to 3. What is actually happening is all the printf statements get outputed to the console after 1 second at the same time.

Output:

Hello from thread 0

Hello from thread 1

Hello from thread 2

Hello from thread 3

Compiler information:

test.c:18:1: warning: non-void function does not return a value [-Wreturn-type]
}
^

test.c:22:5: warning: 'sem_init' is deprecated [-Wdeprecated-declarations]
    sem_init(&semaphore, 0, 4);
    ^

/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/semaphore.h:55:42: note: 'sem_init' has been explicitly marked deprecated here
int sem_init(sem_t *, int, unsigned int) __deprecated;
                                         ^

/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/cdefs.h:204:40: note: expanded from macro '__deprecated'
#define __deprecated    __attribute__((__deprecated__))
                                       ^

test.c:37:5: warning: 'sem_destroy' is deprecated [-Wdeprecated-declarations]
    sem_destroy(&semaphore);
    ^

/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/semaphore.h:53:26: note: 'sem_destroy' has been explicitly marked deprecated here
int sem_destroy(sem_t *) __deprecated;
                         ^

/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/cdefs.h:204:40: note: expanded from macro '__deprecated'
#define __deprecated    __attribute__((__deprecated__))
                                       ^

3 warnings generated.
Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • 1
    If you are asking about the warnings then please show them. If the program is not working as intended then please describe the expected behaviour vs actual behaviour. As it is you have not described any specific problem nor asked a specific question. – kaylum Apr 23 '22 at 05:27
  • Edited now, thank you for the suggestion @kaylum – Hayden Labrie Apr 23 '22 at 05:38
  • what is GCD @Rob – Hayden Labrie Apr 23 '22 at 05:39
  • Grand Central Dispatch. It’s how we generally do threading and semaphores in macOS. – Rob Apr 23 '22 at 05:41
  • Sorry I am new to semaphores and threads. I am trying to learn about threads and semaphores right now. – Hayden Labrie Apr 23 '22 at 05:42
  • The first warning is easy enough to fix, just add `return NULL;` to the end of the `void * routine(void * args);` function. – Jeremy Friesner Apr 23 '22 at 05:44
  • This was meant to be done in c or c++. Is the problem because I am not using a linux os? – Hayden Labrie Apr 23 '22 at 05:50
  • Ahh okay I understand. I am trying to practice using a simpler program right now, because I was running into these bugs for my OS project, thus I decided to attempt in a simplified program using semaphores. – Hayden Labrie Apr 23 '22 at 05:55
  • Perhaps https://stackoverflow.com/q/27736618/1271826 helps. – Rob Apr 23 '22 at 06:29
  • Do I put the code that the solution has into a header file and then add it to my file? For some reason when I tried that it did not work. – Hayden Labrie Apr 23 '22 at 06:33
  • You have to be more specific than “did not work”. As kaylum said, “If the program is not working as intended then please describe the expected behaviour vs actual behaviour.” – Rob Apr 23 '22 at 14:23

1 Answers1

0

I am expecting the threads to be created for the routine function where 4 threads exist for 4 void* routine(). It should printf("Hello from thread") every second starting from thread 0 and going to 3.

I would expect that, too, on any machine that provides POSIX-conforming pthreads, POSIX semaphores, and sleep(). Especially if you resolve the first of the warnings -- for example, by adding return NULL; at the end of function routine().

My expectation is fulfilled on my Linux test machine. However, there are comments around various parts of the web suggesting that MacOS does not support unnamed semaphores, which is what you are trying to use by calling sem_init(). As I understand it, this is the significance of the deprecation warnings you report -- the functions are there, but (I guess) they don't actually work.

If indeed MacOS's sem_init() is non-functional, then calls to it should return an error code. You don't know whether that's happening, because you don't check for it. Always check your functions' error indicators if in fact you care whether they succeeded (and here, you certainly do).

One possible workaround that does not require abandoning POSIX interfaces would be to switch to named semaphores instead of unnamed ones. That would involve using sem_open() and sem_close() instead of sem_init() and sem_destroy().

What is actually happening is all the printf statements get outputed to the console after 1 second at the same time.

That certainly sounds like the semaphore is not working. Your threads are working, because you get the output at all, and they are running in parallel, because their sleep()s all expire at about the same time. Again, check the error indicators of your function calls (their return values for all library functions in the example code), as this will often clue you in when something does not work as you expect, whether because of something wrong with your code or because erroneous data or runtime environment.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157