C语言 macos上的POSIX信号量



我正在尝试创建一个信号量,并通过使用这个简单的程序进行练习,尽管我在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 %dn", *(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个线程存在4个void* routine()。它应该从线程0开始,直到线程3,每秒打印一次("Hello from thread")实际发生的情况是,所有的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.

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

我也希望在任何提供符合POSIX标准的pthread、POSIX信号量和sleep()的机器上也是如此。特别是如果您解决了第一个警告—例如,通过在函数routine()的末尾添加return NULL;

我的期望在我的Linux测试机上实现了。然而,在网络的各个部分都有评论表明MacOS不支持未命名的信号量,这就是你试图通过调用sem_init()来使用的。正如我所理解的,这就是你报告的弃用警告的意义——函数在那里,但(我猜)它们实际上不起作用。

如果MacOS的sem_init()确实是无效的,那么调用它应该返回一个错误代码。你不知道这是否发生了,因为你没有检查它。总是检查函数的错误指示器,如果实际上你关心它们是否成功(在这里,你当然关心)。

不需要放弃POSIX接口的一个可能的解决方案是切换到命名信号量而不是未命名信号量。这将涉及使用sem_open()sem_close()而不是sem_init()sem_destroy()

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

这听起来肯定像信号量不工作。您的线程正在工作,因为您得到了输出,并且它们是并行运行的,因为它们的sleep()都在大约同一时间过期。同样,检查函数调用的错误指示器(示例代码中所有库函数的返回值),因为这通常会在某些事情不像您期望的那样工作时提示您,无论是由于代码错误还是由于错误的数据或运行时环境。

相关内容

  • 没有找到相关文章

最新更新