我有一个脚本,它使用一个非常简单的基于文件的IPC与另一个程序通信。我用新内容编写一个tmp文件,并mv
将其保存到IPC文件中,以保存atomar(另一个程序侦听重命名事件)。你知道吗
但现在的问题来了:这种方法可以工作2到3次,但之后交换就卡住了。你知道吗
time.sleep(10)
# check lsof => target file not opened
subprocess.run(
"mv /tmp/tempfile /tmp/target",
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
shell=True,
)
# check lsof => target file STILL open
time.sleep(10)
/tmp/tempfile
将为每次写入做好准备
第一次运行的结果是:
$ lsof /tmp/target
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
python 1714 <user> 3u REG 0,18 302 10058 /tmp/target
在我终止python主程序之前保持打开状态。连续运行会像预期的那样更改内容、inode和文件描述符,但它仍然是打开的,这是我不希望从mv
中看到的。你知道吗
当包含以上这些行的python程序被关闭时,文件最终被关闭。你知道吗
编辑:
发现错误:错误处理tempfile.mkstemp()
。见:https://docs.python.org/3/library/tempfile.html#tempfile.mkstemp
我创建了tempfile,如下所示:
_fd, temp_file_path = tempfile.mkstemp()
在这里,我丢弃了filedescriptor_fd
,它在默认情况下是打开的。我没有关上它,所以即使在搬家后它仍然开着。这导致了一个打开的目标,因为我只是在目标上lsof
,我没有看到tempfile已经打开了。这将是正确的版本:
fd, temp_file_path = tempfile.mkstemp()
fd.write(content)
fd.close()
# ... mv/rename via shell execution/shutil/pathlib
非常感谢大家的帮助和建议!你知道吗
有什么理由不使用shutil.move?否则,可能需要等待
mv
命令完成移动,然后杀死它,读取stdin,运行类似当然
terminate
会有点苛刻。你知道吗Edit:根据您的使用情况,
rsync
不是python的一部分,它可能是一个优雅的解决方案,可以在网络上保持数据同步,而无需编写一行代码您说它仍然是由“mv”打开的,但您不知道python显示的结果是如何打开的。由于它是一个子进程,请查看pid是否与python进程相同,可能是另一个python进程。你知道吗
我无法重现这种行为。我创建了一个文件
/tmp/tempfile
,并运行了一个python脚本,其中包含subprocess.run
调用,然后是长时间睡眠。/tmp/target
没有被使用,也没有在lsof -p <pid>
中看到任何意外打开的文件。你知道吗(edit)我对此并不感到惊讶,因为您的subprocess命令不可能打开文件:
mv
不打开它的参数(您可以用ltrace
检查它),并且subprocess.run
不解析它的参数或对它做任何操作,除了将它传递给exec
-ed之外但是,当我添加一些行来打开一个文件并对其进行写入,然后移动该文件时,我看到的行为与您描述的相同。代码如下:
在这种情况下,文件仍然处于打开状态,因为它从未关闭过,而且即使已重命名,原始文件句柄仍然存在。我敢打赌,您的代码中有类似的东西,创建这个文件并为它留下一个打开的句柄。你知道吗
相关问题 更多 >
编程相关推荐