gpt4 book ai didi

python-multithreading - 理解这个多线程恶魔python代码

转载 作者:行者123 更新时间:2023-12-02 01:44:47 25 4
gpt4 key购买 nike

所以我是 python 的初学者,正在研究文件系统事件处理程序。我遇到了 watchdog api,在那里我看到了一段我无法理解的多线程代码。

这是他们网站上发布的代码:

import sys
import time
import logging
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler

if __name__ == "__main__":
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
path = sys.argv[1] if len(sys.argv) > 1 else '.'
event_handler = LoggingEventHandler()
observer = Observer()
observer.schedule(event_handler, path, recursive=True)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()

此代码运行一个无限循环并监听某个文件夹并将看到的内容记录到控制台。我的疑问在于代码的底部。

所以你启动了观察者。然后让它继续无限循环,直到完成一些按键操作。我假设在“observer.start()”代码的某处,他们也设置了 daemon=True。按下某些键后,程序会退出循环并停止观察者。在 watchdog 的 api 中,stop() 的定义表示它会停止守护线程。

1) 然后它执行 join()。但是这个加入需要什么。我已经停止了守护线程。 join() 不是意味着等待所有线程停止,然后才退出程序。我可以从代码中删除 join() 吗?删除它后,我的程序仍然可以正常运行。

2) 我也不明白 while 循环中 sleep(1) 的必要性。如果我在那里放一个“通过”声明会发生什么。我假设 while 循环会消耗更多资源???我们将休眠时间设置为 1 秒而不是 2-3 秒的原因是,在最坏的情况下,用户可能需要等待 2-3 秒才能关闭程序。但我可能错了。

最佳答案

  1. 请记住守护进程在父进程中运行,嗯,过程。您需要在该线程时保持父进程处于事件状态正在执行,否则它会在程序退出时被杀死(并且可能以一种不优雅的方式)。 join 确保过程保持事件状态,直到所有线程实际退出;仅仅因为您调用了 stop 并不能保证线程实际上已完成执行。 stop 是线程停止的请求,它不需要阻塞直到线程终止(也不应该这样,以便父线程可以调用 stop 在许多子线程上“一次”)。

  2. 这纯粹是为了减少 CPU 消耗。如果您只是通过
    在那里,CPU 会尽可能快地运行那个 while 循环,从而减少循环。 sleep 调用主动让出 CPU 给其他进程,因为它知道不需要对任何特定条件做出快速响应。您基本上是正确的,它是 sleep(1),因此最坏情况下的响应时间大约为 1 秒。

更新:

这里是一个例子,说明为什么有一个join 很重要。假设以下内容在线程中运行:

while not self.stop:  # self.stop is set to True when stop() is called
...
self.results.append(item) # do some stuff that involves appending results to a list
with open('~/output.txt', 'w') as outfile:
outfile.write('\n'.join(str(item) for item in item))

当调用stop 时,while 循环将终止,结果文件将打开并开始写入。如果未调用 join,则进程可能会在 write 操作完成之前终止,这会导致结果损坏。 join 确保父线程等待此写入完成。它还确保该过程实际上等待该 while 循环的整个迭代完成;如果没有 join,您不仅会错过文件写入,而且还会在 while block 的中间终止。

但是,如果调用了 stop 的线程在 while 终止后很长时间没有做任何事情,join 将立即有效返回所以基本上变成了 NOP。

更新 2:

关于 sleep 调用,某些事件(例如 ctrl+c)甚至可以从父进程的 sleep 调用中冒出。所以在这种特殊情况下, sleep 时间的长短并不是那么重要。将它设置为 1 秒主要是为了明确表示您基本上是在执行“让出 CPU”而不是真正在 sleep 。

关于python-multithreading - 理解这个多线程恶魔python代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26342183/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com