3

mmap()用于共享内存(来自 Linux 或其他类 UNIX 系统)时,是否可以(并且可移植)使用fcntl()flock()lockf()函数)来协调对映射的访问?

对这个 SO question的回应似乎表明它应该起作用。

我想到的想法是使用进程/页面映射来构建共享内存,以最大限度地减少锁定争用。进程可以同时使用它们的页面,并且只需要在更新进程/页面映射时获取锁。(从无主页面读取访问将涉及检查序列号,复制所需数据,然后验证该块的序列号没有更改)。

从概念上讲,每个共享这个文件映射的进程都会执行mmap(),在其中找到一个空闲块,获取进程/页面区域的锁,用自己的分配更新它,释放锁,然后愉快地继续它的工作。任何进程都可以搜索过时的映射(使用kill()零作为信号)并清理进程/页表映射。

(粗略的通用术语,我正在玩弄一个生产者/消费者处理引擎,它使用来自 Linux 上的 Python 共享内存;我希望该解决方案可以移植到 BSD 和其他编程语言 --- 只要支持mmap()以及必要的接口fcntl()flock()或者lockf(). 我也对显示如何测量锁争用和检测任何同步失败的伪代码感兴趣。我知道线程多处理及其各自Queue()的对象是实现Python 生产者/消费者处理模型)。

4

1 回答 1

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 访问它。

于 2010-11-27T09:48:23.000 回答