将mmap()
用于共享内存(来自Linux或其他类UNIX系统)时,可以(并且可移植)使用fcntl()
(或flock()
或{{1} } functions)协调对映射的访问?
对this SO question的回应似乎表明它应该有效。
我想到的想法是将共享内存与进程/页面映射结构化,以最小化锁定争用。进程可以同时处理它们的页面,并且只需要在更新进程/页面映射时获取锁定。 (从无主页面读取访问权限将涉及检查序列号,复制所需数据,然后验证该块的序列号未更改)。
从概念上讲,每个共享此文件映射的进程都会执行lockf()
,在其中找到一个空闲块,获取对进程/页面区域的锁定,使用自己的赋值更新它,释放锁定然后继续执行与它的工作。任何进程都可以搜索过时的映射(使用mmap()
并将零作为信号)并清理进程/页表映射。
(粗略地说,通用术语,我正在使用Python上的共享内存使用生产者/消费者处理引擎;我希望解决方案可以移植到BSD和其他编程语言 - 这么久作为支持kill()
以及mmap()
,fcntl()
或flock()
的必要接口,我也对psuedo-code感兴趣,该代码显示了如何测量锁争用并检测任何同步失败。我知道线程和多处理及其各自的lockf().
对象是实现Python生产者/消费者处理模型的最直接的方法。
答案 0 :(得分:1)
我确信锁会提供相互排斥,但我不知道它们是否会给你一个记忆障碍。似乎跳进内核(fcntl,flock和lockf将会这样做)可能会执行某些强制乱序内存读取和写入提交,但我怀疑你会得到一个很难保证。我认为这是它可能有效的事情之一,测试将证明它确实有效,但你不会知道它总是有效,除非你找到一个参考说明。
我在C中做过类似的事情,但我在共享内存中使用了原子自旋锁。过去你必须做一些内联汇编,但gcc现在有一些你可以使用的内在操作:
http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html
如果你愿意编写一个非常简单的Python扩展,你可以包装__sync_lock_test_and_set(...)和__sync_lock_release(...)来做你需要的。那些应该是非常便携的。
我相信有一种方法可以将pthread互斥锁放入共享内存,但我对此没有任何经验。同样,您必须编写一个简单的C扩展来从Python中访问它。