POSIX 共享内存中的未命名信号量未响应 post 或等待

POSIX unnamed semaphore in shared memory is not responding to post or wait

我有一个未命名的信号量,我按照我找到的方法将其放置在一个进程的共享内存中 here on SO

在 P0 中:

/* addr is a pointer to the base of the shared memory area */
sem_t *sem = (sem_t*) addr;
void *usableSharedMemory = (char*) addr + sizeof(sem_t)
sem_init(sem, 1, 0);

P1:

if ((addr = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {
  exit(EXIT_FAILURE);
}

sem_t *my_sem = (sem_t*) addr;
...
sem_post(my_sem);
...
sem_wait(my_sem);

如果我在 post 前后调用 sem_getvalue(my_sem) 或等待,信号量的值不会改变。我有这样的打印要调试:

int v = 0;
v = sem_getvalue(rsem, &v);
printf("BEFORE-POST:%d\n", v);
sem_post(rsem);
v = sem_getvalue(rsem, &v);
printf("AFTER-POST:%d\n", v);

调用sem_post前后,信号量值为零(0)。

我以前没有使用过这种信号量,但我看到了一些可能会被绊倒的东西。

我对另一个 SO post 所建议的时髦指针数学并不感兴趣,而且我无法从这里判断这两个进程是否实际上在与同一块共享内存通信。

在这种情况下,一个好主意是避免指针数学运算并使用一个结构来覆盖共享内存段,这样你就有了一个清晰的组织,并添加一个幻数,这样每个人都可以判断他们是否获得了有效的段或一些随机的虚假记忆:

#define MYSHM_MAGIC 12345987  // can be anything random-ish

struct mysharedmem {
    int     magicvalue;
    sem_t   MySemaphore;
    void    *UsableMemory;
};

此结构覆盖了您的共享内存段,并允许您使用一致且更具可读性的访问方法,尤其是当您添加各方都同意的其他变量时。创建段的代码应该对其进行初始化:

// in P1 ?
struct mysharedmem *myshm = mmap(NULL, SIZE, ...);

myshm->magic = MYSHM_MAGIC;
sem_init(&myshm->MySemaphore, 1, 0);
...

然后在另一个进程中,一旦获得共享地址,实际上通过检查幻数询问段"did you come from the place I think?"。数字的大小无所谓,双方同意即可。

// In P0 ?
struct mysharedmem *myshm = addr; // obtained somehow

if (myshm->magic != MYSHM_MAGIC)
{
    error - we don't see the special magic number
}
.. do stuff

P0如何获得P1创建的共享内存段句柄?