2012-05-02 45 views
3

現在我正在處理我的項目,並且有關於信號量初始化的問題。其實我在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

我注意到你不會從你的函數返回一個值,即使它被聲明爲返回一個'int'。這應該提出警告 - 是否提出了可能有用的其他警告? (儘管R ..總是正確的,但在錯誤或警告中仍可能有些啓發。) – sarnold

+1

順便說一句,錯誤和警告幾乎不可能在評論中讀取;編輯帖子可能會更好。 :) – sarnold

+0

我返回了一個函數的值形式,實際上我並沒有在這裏粘貼我所有的函數。 – nikigx2

回答

5

Mac OSX不符合規定,不支持sem_init。函數存在,但它默默地失敗或更糟糕,給你一個非工作信號量。

我鼓勵你向Apple提出一個錯誤,因爲這是一個真正的,長期存在的問題,嚴重影響了應用程序的可移植性。抱怨的人越多,修復的希望就越大。

至於它周圍的工作,你可以嘗試找到/寫的所有的POSIX信號功能的替換實現與程序鏈接到,或者你可以切換到使用sem_open代替mmapsem_init。 (只要你已經經歷了爲每個信號映射整個頁面的開銷,sem_open並沒有真正花費你更多的東西。如果這個錯誤真的是一個表演阻止者,當你想要包括您現有的信號量爲struct。)

+2

哇。這是...哇。 – sarnold

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() - 如果有誰知道,請告訴我。