如何使用按键输入安全地停止 Python 个线程
How to safely stop Python threads with key input
在我的应用程序中,我有两个线程。主要的和“线程”。 therad 生成一些数据并将其存储在 python 列表中。主线程周期性地复制“线程”生成的列表的内容。两个线程都有一个无限循环。我的目标是在我按下任意键+输入时停止两个线程。为实现此目标,程序必须在线程 运行ning 时等待键盘输入。我以为我需要另一个线程(可以说是管理器),它只在执行期间等待键盘输入。这是我首先尝试的:
class managerThread(threading.Thread):
is_running = True
def __init__(self):
threading.Thread.__init__(self)
signal.signal(signal.SIGINT, self.kill_all)
signal.signal(signal.SIGTERM, self.kill_all)
def run(self):
input("Press any key+enter to stop: ")
self.is_running = False
def kill_all(self,signum, frame):
print("Process ended with keyboard interrupt")
self.is_running = False
sys.exit(-1)
class thread(threading.Thread):
mgr = managerThread()
mgr.start()
def __init__(self):
threading.Thread.__init__(self)
def run(self):
while (self.mgr.is_running):
print("this is acquiring data")
sleep(2.5)
self.mgr.join()
print("manager stopped")
if __name__ == "__main__":
thread = thread()
thread.start()
while (thread.mgr.is_running):
print("this is copying data")
sleep(3)
thread.join()
print("thread is stopped")
sys.exit(0)
上面的代码正是我想做的。但这似乎不正确。管理器管理所有其他的,但它是在一个从属线程中创建的。另一个问题是人们可能会尝试在不同的线程中创建多个管理器。这是必须严格避免的事情。然后我想manager一定是被managedclasses继承的。这是我尝试过的:
class managerThread(threading.Thread):
is_running = True
def __init__(self):
threading.Thread.__init__(self)
signal.signal(signal.SIGINT, self.kill_all)
signal.signal(signal.SIGTERM, self.kill_all)
self.start()
def run(self):
input("Press any key+enter to stop: ")
self.is_running = False
def kill_all(self,signum, frame):
print("Process ended with keyboard interrupt")
self.is_running = False
sys.exit(-1)
class thread(managerThread):
def __init__(self):
super().__init__()
threading.Thread.__init__(self)
def run(self):
while (self.is_running):
print("this is acquiring data")
sleep(2.5)
print("manager stopped")
if __name__ == "__main__":
thread = thread()
thread.start()
while (thread.is_running):
print("this is copying data")
sleep(3)
thread.join()
print("thread is stopped")
sys.exit(0)
如第二个代码所示,主要部分是相同的。我试图将 thread
作为 managerThread
的 child。但是,这是行不通的。经理从不执行“运行”方法。所以我无法停止其他线程。另一个关键问题是我不知道如何用 join()
停止 super()
。我确定我在 class 继承方面犯了一个错误,但我无法解决问题,因为我没有太多的 OOP 经验,线程使我的困惑加倍。
注意:我不关心线程的同步。
我的问题是:
- 创建管理器线程是否正确以安全地停止从属线程?如果不是,正确的方法是什么?
- 为什么第二个代码不起作用?我必须修改什么才能让它工作?
- 为什么 parent class 正在初始化但它永远不会 运行ning "运行" 方法?
- 我相信 parent class 永远不会开始,但是如果它真的开始了,我怎么能在第二个代码中停止它呢?
谢谢。
即使我不想使用全局变量来安全地停止所有线程,我也找不到没有全局 运行 标志的解决方案。我还尝试将一个可变变量传递给管理器线程,但我没有成功。这是一个工作草图,解释了我如何解决我的问题。我希望这可以帮助别人。同时,如果有人提出更好的解决方案,我会很高兴 :)。
注意:我没有调试
import sys
import threading, queue
import signal
from time import sleep
import numpy as np
global_running = False
class managerThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
signal.signal(signal.SIGINT, self.kill_all)
signal.signal(signal.SIGTERM, self.kill_all)
def run(self):
global is_running
is_running = True
input("Press any key+enter to stop: ")
is_running = False
print("manager finished")
def kill_all(self,signum, frame):
global is_running
is_running = False
print("Process ended with keyboard interrupt")
sys.exit(-1)
class thread(threading.Thread):
__mgr = managerThread()
__mgr.start()
running = True
def __init__(self):
threading.Thread.__init__(self)
self.myvar = 0
self.queue = queue.Queue()
def currentVar(self):
var = np.empty(1)
while (var.size<=1):
var = self.queue.get()
self.queue.task_done()
return var
def run(self):
global is_running
while (is_running):
print("this is acquiring data")
sleep(2.5)
self.myvar = np.empty(5)
self.queue.put(self.myvar)
self.running = False
self.__mgr.join()
print("manager stopped")
if __name__ == "__main__":
thread = thread()
thread.start()
while (thread.running):
# var = thread.queue.get()
var = thread.currentVar()
print ("value is: ", var)
# thread.queue.task_done()
thread.join()
print("thread is stopped")
sys.exit(0)
在我的应用程序中,我有两个线程。主要的和“线程”。 therad 生成一些数据并将其存储在 python 列表中。主线程周期性地复制“线程”生成的列表的内容。两个线程都有一个无限循环。我的目标是在我按下任意键+输入时停止两个线程。为实现此目标,程序必须在线程 运行ning 时等待键盘输入。我以为我需要另一个线程(可以说是管理器),它只在执行期间等待键盘输入。这是我首先尝试的:
class managerThread(threading.Thread):
is_running = True
def __init__(self):
threading.Thread.__init__(self)
signal.signal(signal.SIGINT, self.kill_all)
signal.signal(signal.SIGTERM, self.kill_all)
def run(self):
input("Press any key+enter to stop: ")
self.is_running = False
def kill_all(self,signum, frame):
print("Process ended with keyboard interrupt")
self.is_running = False
sys.exit(-1)
class thread(threading.Thread):
mgr = managerThread()
mgr.start()
def __init__(self):
threading.Thread.__init__(self)
def run(self):
while (self.mgr.is_running):
print("this is acquiring data")
sleep(2.5)
self.mgr.join()
print("manager stopped")
if __name__ == "__main__":
thread = thread()
thread.start()
while (thread.mgr.is_running):
print("this is copying data")
sleep(3)
thread.join()
print("thread is stopped")
sys.exit(0)
上面的代码正是我想做的。但这似乎不正确。管理器管理所有其他的,但它是在一个从属线程中创建的。另一个问题是人们可能会尝试在不同的线程中创建多个管理器。这是必须严格避免的事情。然后我想manager一定是被managedclasses继承的。这是我尝试过的:
class managerThread(threading.Thread):
is_running = True
def __init__(self):
threading.Thread.__init__(self)
signal.signal(signal.SIGINT, self.kill_all)
signal.signal(signal.SIGTERM, self.kill_all)
self.start()
def run(self):
input("Press any key+enter to stop: ")
self.is_running = False
def kill_all(self,signum, frame):
print("Process ended with keyboard interrupt")
self.is_running = False
sys.exit(-1)
class thread(managerThread):
def __init__(self):
super().__init__()
threading.Thread.__init__(self)
def run(self):
while (self.is_running):
print("this is acquiring data")
sleep(2.5)
print("manager stopped")
if __name__ == "__main__":
thread = thread()
thread.start()
while (thread.is_running):
print("this is copying data")
sleep(3)
thread.join()
print("thread is stopped")
sys.exit(0)
如第二个代码所示,主要部分是相同的。我试图将 thread
作为 managerThread
的 child。但是,这是行不通的。经理从不执行“运行”方法。所以我无法停止其他线程。另一个关键问题是我不知道如何用 join()
停止 super()
。我确定我在 class 继承方面犯了一个错误,但我无法解决问题,因为我没有太多的 OOP 经验,线程使我的困惑加倍。
注意:我不关心线程的同步。
我的问题是:
- 创建管理器线程是否正确以安全地停止从属线程?如果不是,正确的方法是什么?
- 为什么第二个代码不起作用?我必须修改什么才能让它工作?
- 为什么 parent class 正在初始化但它永远不会 运行ning "运行" 方法?
- 我相信 parent class 永远不会开始,但是如果它真的开始了,我怎么能在第二个代码中停止它呢?
谢谢。
即使我不想使用全局变量来安全地停止所有线程,我也找不到没有全局 运行 标志的解决方案。我还尝试将一个可变变量传递给管理器线程,但我没有成功。这是一个工作草图,解释了我如何解决我的问题。我希望这可以帮助别人。同时,如果有人提出更好的解决方案,我会很高兴 :)。
注意:我没有调试
import sys
import threading, queue
import signal
from time import sleep
import numpy as np
global_running = False
class managerThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
signal.signal(signal.SIGINT, self.kill_all)
signal.signal(signal.SIGTERM, self.kill_all)
def run(self):
global is_running
is_running = True
input("Press any key+enter to stop: ")
is_running = False
print("manager finished")
def kill_all(self,signum, frame):
global is_running
is_running = False
print("Process ended with keyboard interrupt")
sys.exit(-1)
class thread(threading.Thread):
__mgr = managerThread()
__mgr.start()
running = True
def __init__(self):
threading.Thread.__init__(self)
self.myvar = 0
self.queue = queue.Queue()
def currentVar(self):
var = np.empty(1)
while (var.size<=1):
var = self.queue.get()
self.queue.task_done()
return var
def run(self):
global is_running
while (is_running):
print("this is acquiring data")
sleep(2.5)
self.myvar = np.empty(5)
self.queue.put(self.myvar)
self.running = False
self.__mgr.join()
print("manager stopped")
if __name__ == "__main__":
thread = thread()
thread.start()
while (thread.running):
# var = thread.queue.get()
var = thread.currentVar()
print ("value is: ", var)
# thread.queue.task_done()
thread.join()
print("thread is stopped")
sys.exit(0)