Python守护线程和“with”语句

5
如果我在守护进程线程中有以下代码,并且主线程没有调用守护进程的join方法。当主线程退出时,由于文件在“with”语句中使用,所以文件会安全关闭吗?如果不行,有什么方法可以使其安全关闭吗?谢谢:D
while True:
    with open('file.txt', 'r') as f:
        cfg = f.readlines()
time.sleep(60)
1个回答

8
文档中得知:
注意:在关闭时,守护线程会被突然终止。它们的资源(例如打开的文件、数据库事务等)可能无法正确释放。如果您想使您的线程正常停止,请将其设为非守护线程,并使用适当的信号机制,例如Event。
这表明但并没有直接说明守护线程会在不运行__exit__方法和finally块的情况下结束。我们可以进行实验以验证这一点:
import contextlib
import threading
import time

@contextlib.contextmanager
def cm():
    try:
        yield
    finally:
        print 'in __exit__'

def f():
    with cm():
        print 'in with block'
        event.set()
        time.sleep(10)

event = threading.Event()

t = threading.Thread(target=f)
t.daemon = True
t.start()

event.wait()

在我们启动一个守护线程并将其保持睡眠状态的 with 块中,当主线程退出时。当我们运行实验时,我们会得到以下输出:

in with block

但是没有 __exit__,所以 __exit__ 方法永远不会执行。


如果你想要清理,请不要使用守护线程。使用普通线程,并通过常规线程间通信渠道告诉它在主线程结束时关闭。


谢谢您的快速回答。所以根据我的问题,文件是以读模式保持打开状态?接下来的问题是 - 这是否会使文件无法使用? - Sam Thomas
1
@SamThomas:操作系统应该在进程退出时自动关闭进程打开的文件句柄,但这并不一定会执行像刷新以写模式打开的文件输出缓冲区之类的操作。 - user2357112
那么在这种情况下,如上所述,使用守护进程是安全的,对吗? - Sam Thomas
@Sam:如果所有线程所做的都是_读取_文件(因此在关闭之前无需刷新其输出缓冲区),那么它是安全的。 - martineau
user2357112:您会推荐哪种常规的线程间通信渠道来处理这样的关闭信号?您能在回答中添加一个使用它的示例吗? - martineau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接