如何停止运行代码(包括线程)的终端进程?

Pro*_*ill 5 python linux multithreading

我正在使用线程同时运行多个函数,目的是从多个网站提取天气数据。我通过 Linux 终端运行这些程序,但是无法通过按 ctrl C 取消它们。我想让它们无限期地运行,因此不想添加完成时间,而是宁愿必要时取消它们。有谁知道为什么 ctrl C 不取消它们,以及如何解决这个问题?

Adi*_*tya 5

  1. 使用Ctrl + Break组合键。
  2. Ctrl + Z。这不会停止程序,但会返回命令提示符。然后做ps -ax | grep *%program_name%*。找到与 yopu 想要停止的那一行相对应的行。行中的第一个整数将是程序 ID。尽力kill -9 %id%最终阻止它。
  3. 如果程序也消耗大量资源,您可以top在单独的终端中使用命令来更快地查看 ID。

参考

  • 1. Ctrl + Break 不起作用。2.可能有效(我对linux相当陌生,在终端中工作并试图找出答案),但是我试图将收集的数据写入文本文件,这导致我丢失数据。 (3认同)

fos*_*ock 5

守护线程

简单地使用守护线程来解决这个问题可能很诱人,当只剩下守护线程时,Python 执行将停止,并且不允许它们很好地清理。文档明确指出了这一点:

守护进程线程在关闭时突然停止。它们的资源(例如打开的文件、数据库事务等)可能无法正确释放。如果您希望线程正常停止,请将它们设置为非守护进程并使用合适的信号机制(例如事件)。

让我们听从他们的建议并使用事件。

使用事件

事件是一个简单的标志,可以跨线程安全地设置和读取。在这种情况下,我们将在主线程中创建一个事件,生成一个新线程来执行一些工作,并监听该事件标志,以防它停止工作。

import threading

ended = threading.Event()

def do_work():
    while not ended.is_set():
        # Do your repeated work
        pass

# Let's create and start our worker thread!
new_thread = threading.Thread(target=do_work)
new_thread.start()

try:
    while not ended.is_set():
        ended.wait(1)
except (KeyboardInterrupt, SystemExit):
    print("Cancelling")
    ended.set()
Run Code Online (Sandbox Code Playgroud)

这里的 try/catch 块在主线程中运行,监听KeyboardInterruptSystemExit异常。如果它捕获一个,它将设置stopped标志,允许线程完成其当前循环迭代,并执行它需要的任何清理。