我需要实现一个锁定方案,以便多个进程可以共享一组资源,而“特殊”进程可以获得对该组资源的独占访问。
这些是批处理过程:在每个事务的开始,我建议获取适当的锁,并在最后释放它,无限期。
flock具有我需要的语义(LOCK_SH、LOCK_EX、LOCK_UN)。我使用 Perl Flock.pm 和一个虚拟文件对其进行了试验,该文件的唯一目的是被flock'ed 反对。我对它的速度有多慢感到有些惊讶,而且从时间花费的“顶部”看并不明显。(它不受 CPU 限制,即使正在执行的循环只包含 LOCK_SH 和 LOCK_UN。)我不想为过早优化感到内疚,但我想知道是否flock是管理共享和的标准方法独占访问 *nix 中的共享资源,即使共享资源不是实际文件,或者是否存在我不知道的其他设施。
更新:@msw 正确地猜到我(无意中)锁定了 NFS 文件而不是本地文件。使用本地文件完全消除了我看到的性能损失。我将问题悬而未决,以了解有关“文件锁定”是否真的是解决此类问题的最佳方法的更多信息。
Unix 有大量的锁定系统。您找到的一种称为 BSD 文件锁定,但还有其他文件锁定方法。最重要的是,您还有semaphores、mutex等等。
至于你的直接问题,是的,这是一个非常好的方法。不要担心它需要的时间。就其本质而言,锁定是一项高开销活动。这就是为什么在设计无锁机制方面付出了如此多的努力。
关于你的计划,唯一让我烦恼的是你必须创建的虚拟文件。可能有一种更简单的方法可以达到您想要的目的:mkdir(2). 该调用是原子的,当目录已经存在时,您会收到错误消息。与此相反,open(2)是只与原子O_EXCL,这是不是随处可见。如果可用,它可能无法按预期工作,要么是因为您使用的是 NFSv2,要么是因为您尚未启用NFS 文件锁定守护进程。
该mkdir方法的一个好处是您可以在 shell 脚本中通过mkdir(1). 我看到您正在使用 Perl,但在这种情况下,它是一个内置函数,而不是外部模块。
另一个好处是它可以在没有任何特殊帮助的情况下在 NFS 上工作。您不能两次创建目录。
该mkdir()方法的唯一问题是无法让它等待现有目录消失。也就是说,它不是阻塞锁操作。我建议你用一个定时器把它包裹起来,这样争夺锁的进程大部分时间都在睡觉。我建议你让每个进程等待一段随机的窗口时间。例如,在 100 到 200 毫秒之间,通过usleep(3). 这将创建一种形式的自旋锁。
| 归档时间: |
|
| 查看次数: |
3425 次 |
| 最近记录: |