简体   繁体   English

如何在终止子进程之前关闭子进程中的文件?

[英]How to close a file in a subprocess before terminating the subprocess?

I want to make a subprocess(writer.py) that keeps adding "test" to a file('20180309.txt') every second and maintain the subprocess with another python process(starter.py). 我想制作一个子进程(writer.py),该子进程不断每秒向文件('20180309.txt')添加“测试”,并使用另一个python进程(starter.py)维护该子进程。

It works fine, but one thing that bothers me is that the file object is not closed before terminating the subprocess. 它工作正常,但令我困扰的一件事是在终止子进程之前未关闭the file object I'd like to know if there's a way to close the file object when the subprocess recieves terminate() signal, or if there are other ways to handle this problem. 我想知道子进程收到终止信号时是否有关闭文件对象的方法,或者是否有其他方法可以解决此问题。

#starter.py
import os
import sys
import subprocess

p1 = subprocess.Popen( ["d:\python36-32\python.exe", r"""writer.py"""], shell=False )
print(p1.pid)

try:
    p1.communicate(timeout=5)
except subprocess.TimeoutExpired:
    p1.terminate()




#writer.py
import time
from datetime import datetime

file = open( datetime.now().strftime('%Y-%m-%d') + '.txt', 'a')

while True:
    file.write('test\n')
    file.flush()
    time.sleep(1)

First, any modern OS will close any (non-shared) files that a process has open when it goes away. 首先,任何新式操作系统都会在进程关闭时关闭其打开的所有(非共享)文件。 You do not have to worry about this. 您不必为此担心。

In a more complex application, you might want to worry about partial writes (or parts of any other "transactions" that can't be done atomically), but for simple cases, there's nothing to worry about at all. 在更复杂的应用程序中,您可能要担心部分写入(或原子不能完成的任何其他“事务”的一部分),但是对于简单的情况,根本无需担心。

Meanwhile, the terminate method in subprocess is not meant for polite shutdown requests. 同时, subprocessterminate方法并不适用于礼貌的关机请求。 If you want to shut down the child, there are better ways to send it a message. 如果要关闭孩子,则有更好的方法向它发送消息。 In fact, since the child and parent are both Python, you may be happier using multiprocessing instead of subprocess in the first place. 实际上,由于子代和父代都是Python,因此使用multiprocessing而不是首先使用subprocess multiprocessing可能会更快乐。

That being said, on *nix, terminate happens to send SIGTERM , and SIGTERM is designed for polite shutdown. 就是说,在* nix上, terminate发生发送SIGTERM ,并且SIGTERM 专为礼让关机而设计的。 If you really want to handle this—and don't care about Windows—read the signal library for how to write a signal handler for SIGTERM . 如果您真的想处理这个问题(而不关心Windows),请阅读signal库,了解如何为SIGTERM编写信号处理程序。 From the signal handler, you can set a global "quit next time through the loop" variable. 在信号处理程序中,您可以设置全局“下次通过循环退出”变量。 or call sys.exit (which I think will raise an exception into the top-level code, but don't quote me on that), or whatever else you want. 或致电sys.exit (我认为这会在顶级代码中引发异常,但不要在sys.exit我),或其他任何您想要的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM