【问题标题】:POSIX unnamed semaphore in shared memory is not responding to post or wait共享内存中的 POSIX 未命名信号量未响应发布或等待
【发布时间】:2019-10-29 04:01:31
【问题描述】:

按照我找到的方法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);

如果我在发布或等待之前和之后调用 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)。

【问题讨论】:

  • 你从sem_init()sem_post()sem_wait()得到什么返回值?因为您没有检查其中任何一个是否失败。您也没有展示如何将信号量放入共享内存中,以便其他进程可以访问它。

标签: c posix semaphore shared-memory


【解决方案1】:

我以前没有使用过这种信号量,但我发现有很多事情可能会绊倒。

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

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

#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);
...

然后在另一个过程中,一旦你获得共享地址,实际上段“你来自我认为的地方吗?”通过检查幻数。数值大小无所谓,只要双方同意就行了。

// 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创建的共享内存段的句柄?

【讨论】:

  • 这是个好主意。句柄是通过在共享内存的名称上调用 mmap 以获取共享内存中的第一个字节,然后将该地址转换为 sem_t 指针来获得的。
  • 我不确定我是否看到了最初分配的共享内存的名称,所以这里的问题可能是两个进程没有与同一个内存通信。幻数测试应该证明这一点。
猜你喜欢
  • 2020-09-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-01
  • 2020-08-22
相关资源
最近更新 更多