macOS 上的 POSIX 信号量

问题描述 投票:0回答:2

我正在尝试创建一个信号量并通过使用这个简单的程序进行练习,尽管在 macos 上编译时我收到了一堆已弃用的警告。我一直在寻找并无法找到让信号量在 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;
}

我期望为例程函数创建线程,其中 4 个 void* 例程()存在 4 个线程。它应该 printf("Hello from thread") 从线程 0 开始到线程 3 每秒执行一次。实际发生的情况是所有 printf 语句在 1 秒后同时输出到控制台。

输出:

Hello from thread 0

Hello from thread 1

Hello from thread 2

Hello from thread 3

编译器信息:

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.
c multithreading macos pthreads semaphore
2个回答
0
投票

我期望为例程函数创建线程,其中 4 个 void* 例程()存在 4 个线程。它应该从线程 0 开始到线程 3 每秒打印一次(“Hello from thread”)。

我希望在任何提供符合 POSIX 的 pthreads、POSIX 信号量和

sleep()
的机器上也是如此。特别是如果您解决了第一个警告 - 例如,通过在函数末尾添加
return NULL;
routine()

我的期望在我的 Linux 测试机上得到了满足。然而,网络上的各个部分都有评论表明 MacOS 不支持未命名信号量,而这正是您尝试通过调用

sem_init()
来使用的。据我了解,这就是您报告的弃用警告的重要性 - 功能在那里,但(我猜)它们实际上不起作用。

如果 MacOS 的

sem_init()
确实不起作用,则调用它应该 返回错误代码。你不知道这是否发生,因为你不检查它。 始终检查函数的错误指示器,如果您实际上关心它们是否成功(在这里,您当然会这样做)。

一种不需要放弃 POSIX 接口的可能解决方法是切换到命名信号量而不是未命名信号量。这将涉及使用

sem_open()
sem_close()
而不是
sem_init()
sem_destroy()

实际发生的是所有 printf 语句在 1 秒后同时输出到控制台。

这听起来确实像是信号量不起作用。您的线程正在工作,因为您完全获得了输出,并且它们正在并行运行,因为它们的

sleep()
几乎同时过期。再次,检查函数调用的错误指示器(示例代码中所有库函数的返回值),因为这通常会在某些内容未按预期工作时提示您,无论是因为代码有问题还是因为数据或运行环境错误。


0
投票

我现在讨厌我的 MacBook Pro m1。 我也有同样的问题。 确切的问题是当我们使用 sem_init 函数时它不起作用。 您可以打印该函数的返回号。

int ret = sem_init(&count, 1, 1);
int ter = sem_init(&write, 1, 1);

printf("%d\n", ret);
printf("%d\n", ter);

解决方案是使用windows或linux机器!

© www.soinside.com 2019 - 2024. All rights reserved.