【发布时间】:2021-03-17 20:48:59
【问题描述】:
我想在共享内存中使用匿名信号量来同步多个进程。
虽然多个 POSIX 操作系统提供匿名信号量(通过 sem_init 和相关函数),但 macOS 不支持它们。
我发现 Mach 信号量在 macOS 上可用,但在 semaphore_create 中,我看不到与 sem_init 的 pshared 参数等效,而且我很难找到表明 Mach/XNU 信号量可以实际上用于同步进程而不仅仅是线程。有可能吗?
这是我目前使用信号量的方式(请注意,sema 是一个包含不同类型信号量的结构,具体取决于目标操作系统,例如它在 Linux 上包含一个 sem_t 信号量):
用于初始化信号量:
task_t task = current_task();
semaphore_create(task, &sema->semaphore, SYNC_POLICY_FIFO, value)
等待它:
semaphore_wait(sema->semaphore);
用于等待超时(与 Linux 上的 sem_timedwait 等效的功能):
mach_timespec_t time;
time.tv_sec = seconds;
time.tv_nsec = useconds;
semaphore_timedwait(sema->semaphore, time);
为了发信号:
semaphore_signal(sema->semaphore);
上述所有代码示例实际上都包含在允许提供与操作系统无关的 API 的相应函数中,我在 Linux 上对这些函数执行的测试调用按预期工作,但在 macOS 上等待信号量的进程是从未从其他进程发出信号。
我做错了什么?
编辑
我在the docs找到这个:
信号量可以用在任何可能出现互斥体的地方。这 排除了它们在中断处理程序中或在 调度程序,并强烈建议不要在 VM 系统中使用它。
“调度程序的上下文”究竟指的是什么?如果您正在编写自己的调度程序,或者这是否涉及与调度程序的任何交互(例如:进程),会是这样吗?
在所有情况下,VM 是否意味着它不应该与使用虚拟内存的进程一起使用,换句话说......所有用户进程?
【问题讨论】:
-
免责声明:我从未真正使用过 Mach 信号量,但我使用过 macOS 的 Mach 原语相当多。 问题/建议: 我注意到在用户空间中,
semaphore_t是另一个mach_port_ttypedef,所以我的假设是要在进程之间共享信号量,您需要从创建它的进程到使用 Mach 消息共享它的进程。 (mach_msg) 这就是您共享信号量访问权限的方式吗?如果您只是传输文字整数值,它将不起作用,每个进程都有一个私有端口名称表。 -
谢谢!不,我没有使用
mach_msg感谢您的建议!