python 子线程 和 子进程 正常结束与强制结束

目录

子线程结束
----给子线程设置标志位
----设置子线程为守护线程
----强制终止
子进程强制结束
----设置标志位
----强制结束

子线程结束

想要的目的是, 主线程能够让子线程结束

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()

你可能感兴趣的:(python高级,python,开发语言,后端)