multithreading - How to stop child threads if keyboard exception occurs in python?
问题描述
I'm facing problem with the thread concept i.e I have a function which will create 10 threads to do task. If any key board interruption occurs, those created threads are still executing and i would like to stop those threads and revert back the changes.
The following code sinppet is the sample approach:
def store_to_db(self,keys_size,master_key,action_flag,key_status):
for iteration in range(10):
t = threading.Thread(target=self.store_worker, args=())
t.start()
threads.append(t)
for t in threads:
t.join()
def store_worker():
print "DOING"
解决方案
使这项工作的想法是:
- 您需要一个“线程池”,线程正在检查它们的
do_run
属性是否为假。 - 您需要该池外的“哨兵线程”检查池中的线程状态并根据需要调整
do_run
“线程池”线程的属性。
示例代码:
import threading
import random
import time
import msvcrt as ms
def main_logic():
# take 10 worker threads
threads = []
for i in range(10):
t = threading.Thread(target=lengthy_process_with_brake, args=(i,))
# start and append
t.start()
threads.append(t)
# start the thread which allows you to stop all threads defined above
s = threading.Thread(target=sentinel, args=(threads,))
s.start()
# join worker threads
for t in threads:
t.join()
def sentinel(threads):
# this one runs until threads defined in "threads" are running or keyboard is pressed
while True:
# number of threads are running
running = [x for x in threads if x.isAlive()]
# if kb is pressed
if ms.kbhit():
# tell threads to stop
for t in running:
t.do_run = False
# if all threads stopped, exit the loop
if not running:
break
# you don't want a high cpu load for nothing
time.sleep(0.05)
def lengthy_process_with_brake(worker_id):
# grab current thread
t = threading.currentThread()
# start msg
print(f"{worker_id} STARTED")
# exit condition
zzz = random.random() * 20
stop_time = time.time() + zzz
# imagine an iteration here like "for item in items:"
while time.time() < stop_time:
# the brake
if not getattr(t, "do_run", True):
print(f"{worker_id} IS ESCAPING")
return
# the task
time.sleep(0.03)
# exit msg
print(f"{worker_id} DONE")
# exit msg
print(f"{worker_id} DONE")
main_logic()
这个解决方案不会“杀死”线程,只是告诉他们停止迭代或他们所做的任何事情。
编辑:我刚刚注意到“键盘异常”在标题中,而不是“任何键”。键盘异常处理有点不同,这里有一个很好的解决方案。要点几乎相同:如果满足条件,则告诉线程返回。
推荐阅读
- javascript - 如何在 javascript 中计算 Vandermonde 矩阵的逆矩阵?
- python - 使用 Python 和 Beautifulsoup 抓取 ASOS 产品价格的网页
- image-processing - 缩小比例时双线性插值如何工作?
- c++ - 全局静态对象销毁后是否可以调用 OS 计时器回调?
- python - 完成文件中的 URL 列表循环时未提供架构
- html - html表格输入数据输入txt文件
- python - 如何检查两个变量是否引用同一个熊猫对象?
- php - 在laravel的where条件下使用数组
- css - BUG - iOS 设备上的 CSS 媒体查询
- python - 如何在同一个文本输入框中实现实时降价预览?