目录
子线程结束
----给子线程设置标志位
----设置子线程为守护线程
----强制终止
子进程强制结束
----设置标志位
----强制结束
子线程结束
想要的目的是, 主线程能够让子线程结束
1. 给子线程设置标志位, 使用threading.Event() 或者其他任何形式的标志, True | False都一样的, 这里使用这个, 主要是没见过, 花里胡哨的用一下
import threading
import time
class StoppableThread(threading.Thread):
def __init__(self):
super(StoppableThread, self).__init__()
self._stop_event = threading.Event()
self._stop_event.clear()
def stop(self):
self._stop_event.set()
def stopped(self):
return self._stop_event.is_set()
def run(self):
while not self.stopped():
print 1
s = StoppableThread()
# s.setDaemon(True)
s.start()
time.sleep(1)
s.stop()
s.join()
在run
方法里面, 通过标志位来决定是否执行
2. 设置子线程为守护线程
import threading
import time
class StoppableThread(threading.Thread):
def __init__(self):
super(StoppableThread, self).__init__()
self._stop_event = threading.Event()
self._stop_event.clear()
def run(self):
while True:
print 1
s = StoppableThread()
s.setDaemon(True)
s.start()
time.sleep(1)
s.join()
上面主线程结束, 那么守护线程也会跟着结束
3. 强制终止
def _async_raise(tid, exc_type):
import inspect
import ctypes
if not inspect.isclass(exc_type):
raise TypeError("Only types can be raised (not instances)")
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid), ctypes.py_object(exc_type))
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, 0)
raise SystemError("PyThreadState_SetAsyncExc failed")
class ExceptionThread(threading.Thread):
def get_my_tid(self):
if not self.isAlive():
raise threading.ThreadError("the thread is not active")
# do we have it cached?
if hasattr(self, "_thread_id"):
return self._thread_id
# no, look for it in the _active dict
for tid, tobj in threading._active.items():
if tobj is self:
self._thread_id = tid
return tid
def raise_exc(self, exctype):
_async_raise(self.get_my_tid(), exctype)
def run(self):
while True:
print 1
e = ExceptionThread()
e.start()
time.sleep(1)
e.raise_exc(ExceptionThread)
不要用这种方式, 有正规的途径, 就别用这种奇技淫巧, 因为进程结束要释放资源, 最好手动释放下, 不然容易出现意料之外的错误
子进程强制结束
1. 设置标志位
python控制exe, 并进行输入输出
通过这篇文章中的方法, 进行父子进程的通信, 当然, 用socket写一个也完全没有问题
, 然后通过发送消息, 子进程主动释放资源, 关闭, 如使用sys.exit(0)
, os._exit()
等
2. 强制结束
但是子进程如果是多线程的话, 感觉不是很稳定, 有些时候任务管理器中还是会发现僵尸进程
import psutil
sub = subprocess.Popen(start_bat, cwd=src_dir, shell=True)
process = psutil.Process(sub.pid)
for proc in process.children(recursive=True):
proc.kill()
process.kill()