有没有快速的方法(即最小化答案时间)来确定文件是否在Linux上打开?
假设我有一个进程将一个文件写入一个目录,另一个进程读取这些文件一旦完成编写,后一个进程可以知道文件是否仍在写入通过前一个过程?
如果可能的话,基于Python的解决方案将是理想的。
注意:我知道我可以使用基于FIFO /队列的解决方案,但我正在寻找其他的东西。
答案 0 :(得分:8)
您当然可以使用Linux的INOTIFY功能,但避免这种情况更安全:让编写过程创建文件(比如data.tmp),读取过程肯定会忽略这些文件。当作者完成时,它应该只为读者重命名文件(比如说.dat)。重命名操作保证不会产生误解。
答案 1 :(得分:4)
如果您知道写入过程的PID,在Linux中您只需查询/ proc / {PID} / fd /并查看其中一个链接是否指向您的某个文件。
你要做的是,扫描目录,归档fd 5(比如说)指向/var/data/whatever/file1.log的事实。然后将指向的文件存储到数组中。
此时如果文件名在数组中,则该进程正在使用它。
所以:
import os
# Here I use PID = 31824
path="/proc/%d/fd" % 31824
openfiles = [ os.readlink("%s/%s" % (path, fname)) for fname in os.listdir(path) ]
if whatever in openfiles:
# whatever is used by pid 31824.
答案 2 :(得分:1)
如果您可以更改“第一个”流程逻辑,那么简单的解决方案就是将数据写入临时文件,并在写完所有数据后重命名该文件。
答案 3 :(得分:1)
lsof | grep filename
。
答案 4 :(得分:1)
您有多种选择:
答案 5 :(得分:1)
如果您知道(或可以找到)写入过程的进程ID,则可以使用psutil库。 sudo pip install psutil
获取图书馆。文档在这里:http://pythonhosted.org/psutil/
>>> import psutil
>>> import os
>>> p = psutil.Process(os.getpid())
>>> p.open_files()
[]
>>> f = open('foo.txt', 'w')
>>> p.open_files()
[openfile(path='/Users/mariaz/Downloads/foo.txt', fd=3)]
如果您无权访问写入过程,则需要以root身份运行lsof并自行解析输出。
答案 6 :(得分:1)
这是使用inotify的解决方案。在写入操作之后,您将收到关闭目录中每个文件的通知。
import os
import pyinotify
def Monitor(path):
class PClose(pyinotify.ProcessEvent):
def process_IN_CLOSE(self, event):
f = event.name and os.path.join(event.path, event.name) or event.path
print 'close event: ' + f
wm = pyinotify.WatchManager()
notifier = pyinotify.Notifier(wm, PClose())
wm.add_watch(path, pyinotify.IN_CLOSE_WRITE)
try:
while 1:
notifier.process_events()
if notifier.check_events():
notifier.read_events()
except KeyboardInterrupt:
notifier.stop()
return
if __name__ == '__main__':
path = "."
Monitor(path)
但是,由于您是控制编写文件的过程的人,因此我会投票选出涉及流程之间某种通信的不同解决方案。
答案 7 :(得分:0)
您可以检查文件的修改时间,看看文件是否在一段时间内未被修改。由于文件可以在更新模式下打开并且可以随时修改,因此您无法100%确定它永远不会被修改。
答案 8 :(得分:0)
我会使用psutil(https://github.com/giampaolo/psutil),它还具有跨平台的优势,并提供许多其他有用的系统功能。
答案 9 :(得分:0)
您可以将 lsof 与子流程
一起使用(output,error) = subprocess.Popen("lsof #absolute_file_path").communicate()
答案 10 :(得分:0)
你可以使用fcntl模块,afaik,它有与C函数相同的fcntl函数,所以像fcntl(fd, F_GETFL)
这样的东西可能有用,但我不确定。您是否可以通过在写入模式下打开来检查目标文件是否被阻止写入?