def isRunning(process_name):
try:
process=len(os.popen('tasklist | findstr '+process_name).readlines())
if process >=1 :
return True
else:
return False
except:
print("程序错误")
return False
def task_killer():
while 1:
if isRunning('Taskmgr.exe'):
os.system('taskkill /IM Taskmgr.exe')
time.sleep(1)
以上代码用来干掉 Taskmgr.exe 进程,使用 Threading 模块的 Thread 实现多线程
t1 = threading.Thread(target=task_killer)
t1.start()
现在想问怎么终止这个线程,t1.join 没用,还会堵塞,t1.join(1)也没用,google 找了以下代码也没用
def _async_raise(tid, exctype):
"""raises the exception, performs cleanup if needed"""
tid = ctypes.c_long(tid)
if not inspect.isclass(exctype):
exctype = type(exctype)
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
if res == 0:
raise ValueError("invalid thread id")
elif res != 1:
# """if it returns a number greater than one, you're in trouble,
# and you should call it again with exc=NULL to revert the effect"""
ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
raise SystemError("PyThreadState_SetAsyncExc failed")
def stop_thread(thread):
'''强制关闭某一个线程'''
_async_raise(thread.ident, SystemExit)
谢谢!
1
BrettD 2022-02-19 17:40:45 +08:00
你在线程里面死循环,join 当然会阻塞了
|
2
ClericPy 2022-02-19 18:06:23 +08:00
因为用的 OS thread 基本没有太粗暴的外部 kill 方式 (这也是我喜欢协程的原因, 虽然协程很多时候比线程费劲太多. 有时候真想外部 kill 就用进程当线程也可以)
早年间 Google 上搜 how to kill thread python 一大把原因和各种花哨操作实际并没什么卵用 所以只能线程内部自己结束标识或者设置守护线程什么的 |
3
ho121 2022-02-19 20:53:59 +08:00 via Android
|
4
zhttp 2022-02-19 22:05:12 +08:00
这种一般是弄个标志吧,每次循环检查一下。
|
5
ysc3839 2022-02-19 22:50:08 +08:00 1
怀疑是 X-Y Problem https://coolshell.cn/articles/10804.html
为什么要 kill taskmgr.exe ?为什么杀进程还用调用命令行工具这么低级的方法,不直接调用 API ?为什么要从外部终止这个线程?用个变量让线程自己停止不行吗? |
6
beastk 2022-02-20 00:06:27 +08:00 via iPhone
没什么好办法,试试 func_timeout 吧,超时就退出,注意会增加近一半多的线程
|
7
hallDrawnel 2022-02-20 00:24:59 +08:00
python 的多线程就是这么难搞。我自己的小项目直接放弃,用多进程,然后就可以很舒适的中断了。
|
8
haoliang 2022-02-20 01:07:15 +08:00
可以用 threading.Event 来做。 我来给个具体示例,通过 ctrl-c 触发 signal interrupt 退出程序。
这事看不出 python 的多线程难搞;没有提供主动终止线程的原因,我想有这个原因:线程与同进程的其他线程共享资源,如果不能做 cleanup 就被终止,会出现 fd 泄漏之类的问题; 而进程不同,操作系统会兜底 ``` #!/usr/bin/env python3 import signal import time from threading import Event, Thread def killer(stop: Event): while True: if stop.is_set(): print("killer: canceled") break print("killer: working") time.sleep(1) def main(): stop = Event() def handle_sigint(*args): stop.set() signal.signal(signal.SIGINT, handle_sigint) th = Thread(target=killer, args=[stop]) th.start() th.join() print("main thread exiting") if __name__ == "__main__": main() ``` |
9
yingxiangyu 2022-02-20 01:42:10 +08:00
换进程,如果出现 pickle 报错,就用 pathos import pathos
Process = pathos.helpers.mp.Process |
10
yolee599 2022-02-20 16:33:00 +08:00
task_killer 里不要 while(1),要 while (quit_flag),你要结束线程的时候先置 quit_flag 为 0 ,再 join
|
11
009694 2022-02-21 08:43:38 +08:00 via iPhone
从外部去 kill 一个毫无准备的线程 这本来就是很邪恶的做法。。为什么要提供这种机制 就是为了防止又菜又爱钻空子的人去用 最后变成很多人都在用
|
12
18870715400 2022-02-23 17:06:49 +08:00
你的 while 1 没有退出的标志肯定会一直执行下去的呀。
|