如何在Linux中序列化对目录的访问?

时间:2015-06-25 07:01:57

标签: c linux apache-spark semaphore

假设处理器上正在运行4个并发进程,并且需要将数据从HDFS(与Spark一起使用)文件系统复制到本地目录。现在我只想要一个进程来复制该数据,而其他进程只是等待第一个进程复制该数据。

所以,基本上,我想要某种信号量机制,其中每个进程都试图获取信号量来尝试复制数据,但只有一个进程获得信号量。所有未能获取信号量的进程将等待信号量被清除(能够获取信号量的进程在完成复制后将其清除),当它被清除时,他们知道数据已被复制。我怎么能在Linux中做到这一点?

2 个答案:

答案 0 :(得分:1)

有很多不同的方法来实现信号量。经典的System V信号量方式在man semop中描述,更广泛地在man sem_overview中描述。

您可能仍希望做一些更容易扩展和现代化的事情。许多IPC框架(Apache也有一个或两个)具有原子IPC操作。这些可以用于实现信号量,但我要非常小心。

通常,我经常鼓励编写多进程或多线程应用程序的人使用C ++而不是C。如果你的状态被很好地封装在一个状态中,那么通常更容易看到共享状态必须受到保护的位置。可以自己锁定的对象。因此,我建议你看一下Boost's IPC synchronization mechanisms

答案 1 :(得分:1)

除了Marcus Müller's answer之外,您还可以使用某种file locking机制进行同步。

文件锁定在网络或远程文件系统上可能无法正常工作。您应该在本地安装的文件系统(例如Ext4,BTRFS,...)上使用它,而不是在远程文件系统上(例如NFS)

例如,您可以采用您的目录包含的约定(或者您将创建它)某些.lock文件并使用建议锁 flock(2)在访问目录之前,.lock文件上的(或POSIX lockf(3))。

如果使用flock,您甚至可以直接锁定目录....

使用这种文件锁定方法的优点是您可以使用flock(1)

编写shell脚本

在Linux上,您也可以使用inotify(7)(例如,在该目录中创建某个文件时收到通知)

请注意,大多数解决方案都是(咨询,因此)预先假定访问该目录的每个进程都遵循某些约定(换句话说,没有像使用flock(1)这样的更多预防措施,粗心的用户可以访问该目录 - 例如,当您的锁定进程正在访问目录时,一个普通的cp命令 - 或其下的文件。如果您不接受,那么您可能会寻找mandatory file locking(这是某些Linux内核和文件系统的一个功能,AFAIK已被弃用)。

顺便说一句,你可能会阅读更多有关ACID属性的内容,并考虑使用某些数据库等......