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);   
4

2 に答える 2

5

Mac OSXは非準拠であり、をサポートしていませんsem_init。この機能は存在しますが、黙って失敗するか悪化し、セマフォが機能しなくなります。

これはアプリケーションの移植性に悪影響を及ぼしている実際の長年の問題であるため、Appleにバグを報告することをお勧めします。不平を言う人が多ければ多いほど、それを修正することへの希望が高まります。

これを回避するには、すべてのPOSIXセマフォ関数の代替実装を見つけて作成し、プログラムをそれにリンクするか、およびsem_openの代わりに使用に切り替えることができます。mmapsem_init

(セマフォごとにページ全体をマッピングするオーバーヘッドをすでに経験している限り、実際にsem_openはそれ以上の費用はかかりません。このバグが本当に目立たないのは、既存のセマフォ内にセマフォを含めたい場合です。struct。)

于 2012-05-02T02:14:53.807 に答える
0

MacOSXには回避策があります。

#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()ません。誰か知っている場合は、お知らせください。

于 2014-09-06T03:30:15.813 に答える