2011-02-15 180 views
3

我有一个守护程序,它接受套接字连接并根据连接的性质读取或写入一组动态文件。因为我的守护进程是多线程的,所以可能存在相同的文件可能被多个线程写入。由于我的文件列表是动态的,并且不是固定的,我不确定如何让一个线程不会碰到另一个线程。出于性能方面的考虑,我希望线程能够同时写入不同的文件,而不是同时写入不同的文件。线程安全多文件写入

其他问题建议使用互斥锁,但我不完全清楚在这种情况下互斥锁将如何帮助 - 文件列表是动态的,只有线程已知。

在这种情况下使用文件锁定是否合适?如果是这样,那么如何以线程安全的方式实现文件锁定?

+0

无论如何,你需要对每个文件进行互斥访问 - 你可以用Matthew PK的“文件代理”概念来做到这一点,或者甚至只是一个从(绝对)文件名到互斥量的散列表(显然是修改散列表本身也应该使用互斥量序列化)。 – 2011-02-15 00:34:35

+1

@Conrad Meyer:散列`st_dev` /`st_ino`组合可能比文件名更好,因为与实际上唯一标识文件的文件名不同。 – caf 2011-02-15 05:27:33

回答

2

flock会工作正常。它不锁定文件描述符,它锁定实际的文件。

已被排除在外的文件不能被另一个进程或线程独占锁定。这将打破锁的整个目的。

请注意,这些锁是咨询。一个不使用flock的进程可以愉快地覆盖该文件,即使另一个进程拥有独占权。

1

我会使用事件代理模式。每个插入线程触发一个事件(具有文件的参数),然后事件由中央文件代理处理,并带有当前正在写入的共享文件集合。

如果无法写入文件,请决定要做什么......否则报告成功。

多个侦听器,一个中央文件锁集合,多个作者。

1

我不能说这将是“最佳”的解决方案,但我建议是这样的:

维护一个包含两个东西一个结构的链接列表:

  1. 的filename
  2. 与文件关联的条件等待变量。

流A.当守护进程接收到请求时,互斥锁锁定列表并检查文件名是否在列表中。如果不是,则使用新条件等待变量为链接列表添加一个新条目,供其他线程使用。释放互斥锁。执行文件操作。完成后,锁定链接列表并除去该文件的结构条目,然后通过等待对象发信号通知其他线程。

流B.如果请求来自同一个文件,它将锁定列表并查找包含在列表中的文件名。如果它在列表中,请抓住等待变量并等待它。当线程被发信号时,在列表上抓住一个锁并查看文件是否在列表中(可能是另一个线程在你之前拿到了文件名上的锁)。如果不是,请按照流程A进行操作。如果是,请抓取新结构中的等待变量并再次等待,直到发出信号,然后再次执行上述步骤。