现在我正在处理我的项目,我有一个关于信号量初始化的问题。实际上我是在Mac OS X上编程,但我试图在Linux上编译我的项目并且它不能编译。在OS X上,它会编译,但每次只是在初始化时崩溃。
sem_t *mutex_1, *mutex_2, *mutex_3, *reader, *writer;
int initialization_semaphores (void)
{
int ERROR = EOK;
if ((mutex_1 = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, 0, 0)) == MAP_FAILED)
ERROR = ESEM;
if ((mutex_2 = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, 0, 0)) == MAP_FAILED)
ERROR = ESEM;
if ((mutex_3 = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, 0, 0)) == MAP_FAILED)
ERROR = ESEM;
if ((reader = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, 0, 0)) == MAP_FAILED)
ERROR = ESEM;
if ((writer = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, 0, 0)) == MAP_FAILED)
ERROR = ESEM;
if (ERROR == EOK) {
if (sem_init(mutex_1, 1, 1) == -1)
ERROR = ESEM;
if (sem_init(mutex_2, 1, 1) == -1)
ERROR = ESEM;
if (sem_init(mutex_3, 1, 1) == -1)
ERROR = ESEM;
if (sem_init(reader, 1, 1) == -1)
ERROR = ESEM;
if (sem_init(writer, 1, 1) == -1)
ERROR = ESEM;
}
}
当我尝试在linux上编译它时,我看到了:
/tmp/ccmkN9G7.o: In function `initialization_semaphores':
readerWriter.c:(.text+0x1a2): undefined reference to `sem_init'
readerWriter.c:(.text+0x1cb): undefined reference to `sem_init'
readerWriter.c:(.text+0x1f4): undefined reference to `sem_init'
readerWriter.c:(.text+0x21d): undefined reference to `sem_init'
readerWriter.c:(.text+0x246): undefined reference to `sem_init'
readerWriter.c:(.text+0x275): undefined reference to `shm_open'
是不是? :
int ERROR = EOK;
mutex_1 = sem_open("mutex1", O_CREAT, S_IRUSR | S_IWUSR, 1);
mutex_2 = sem_open("mutex2", O_CREAT, S_IRUSR | S_IWUSR, 1);
mutex_3 = sem_open("mutex3", O_CREAT, S_IRUSR | S_IWUSR, 1);
reader = sem_open("reader", O_CREAT, S_IRUSR | S_IWUSR, 1);
writer = sem_open("writer", O_CREAT, S_IRUSR | S_IWUSR, 1);
答案 0 :(得分:5)
Mac OSX不符合要求且不支持sem_init
。该函数存在,但它无声地失败或更糟,留下一个不工作的信号量。
我建议你向Apple提交一个错误,因为这是一个真正的,长期存在的问题,严重影响了应用程序的可移植性。抱怨的人越多,就越有希望得到解决。
至于解决它,您可以尝试查找/编写所有POSIX信号量函数的替换实现并将您的程序链接到该函数,或者您可以切换到使用sem_open
而不是mmap
和sem_init
。
(只要您已经完成了为每个信号量映射整个页面的开销,sem_open
并不会让您付出更多的代价。这个错误实际上是一个显示阻塞就在于想要在现有的struct
中包含您的信号量。)
答案 1 :(得分:0)
Mac OSX上有解决方法。
#include <dispatch/dispatch.h>
typedef dispatch_semaphore_t sem_t;
void sem_init(sem_t* sem, bool is_pshared, unsigned value)
{
*sem = dispatch_semaphore_create(value);
}
static void sem_destroy(sem_t* sem)
{
dispatch_release(*sem);
}
static void sem_post(sem_t* sem)
{
dispatch_semaphore_signal(*sem);
}
static void sem_wait(sem_t* sem)
{
dispatch_semaphore_wait(*sem, DISPATCH_TIME_FOREVER);
}
但是,我不知道如何做sem_getvalue()
- 如果有人知道,请告诉我。