在实际操作过程中python可以对进程进行很好的管控,但是对线程来说有的时候却无能为力,比如我利用多线程正在执行一个文件搜索的任务,它需要遍历所有目录需要花很长时间才能遍历完,但是一旦出现我们想要的结果时,我们就终止搜索岂不是更好,ctrl+c就终止所有线程的运行,然后返回主进程不是更符合用户体验。

废话不多说讲讲原理.

思路1:主进程---->子进程{n多个线程}  (没有思路2了)

我可以在主进程开一个子进程,然后在子进程里面再来执行线程,如果我想终止所有线程我就直接杀死子进程,岂不美哉,我们来实践一下,、

import signal,os
from multiprocessing import Process,Queue
from threading import Thread,currentThread
from time import *
grand=[0]  #用来存孙子进程的pid
flag=[0]   #设置跳出chile循环的标志
def quit(signum, frame):
	flag[0]=1
	print("终止了主进程",grand[0])
	try: #使用try是防止程序报错而退出
		os.kill(grand[0],signal.SIGILL)	#os.kill(pid,signal)
	except:
		pass
def threadn(): 
	global counter
	while True:
		#print("tid=",currentThread())
		print("child_pid=",os.getpid())
		sleep(2)
def create_thread_pool():
	ta=[0 for i in range(10)] #创建一个长度为10的列表用于存储10个线程名
	for i in range(10): #创建10个线程
		ta[i]=Thread(target=threadn)
	for ii in range(10):
		ta[ii].start()
	for iii in range(10):
		ta[iii].join()
def process0(q): #子进程process1
	q.put_nowait(os.getpid())
	print("grand pid=",os.getpid())
	#signal.signal(signal.SIGINT,quit) #接收中断信号ctrl+c
	create_thread_pool() #我在子进程创建n个线程

if __name__=="__main__":
	q=Queue()  #实例化消息队列
	while True:
		print("main pid=",os.getpid())
		name=input("please input name:")
		p0=Process(target=process0,args=(q,))
		p0.start()
		sleep(1)
		grand[0]=q.get_nowait()
		signal.signal(signal.SIGINT,quit) #接收中断信号ctrl+c
		while 1:#循环等待不要用join()防止陷入子进程,主进程无法得到时间片而不能响应中断
			if flag[0]:#设置跳出循环的标志,中断处理函数会改变这个值
				break
			sleep(1)

上图中的grand[0]理解为child[0]因为最开始我创建了孙子进程所以名称有点出入,在上面代码看到grand一律当做子进程(child)

 下图在程序运行时按ctrl+c就可以结束子进程

python多线程中线程如何退出 python多线程终止_多线程

2关于Python3多进程程序打包问题

关于打包后子进程无法运行需要multiprocessing的一个freeze_support模块,然后打包后的exe

才能正常输出,否则不会显示任何内容,如下引用模块即可

from multiprocessing freeze_support
if __name__=='__main__':
     freeze_support() #初始化实例

3.消息队列需要注意一下

有时需要用q.get_nowait()不会使代码进入阻塞队列 ,q.get()则会

4.纠正一下信号量的问题

网上好多是使用的SIGKILL 而实际是SIGILL  少了一个K,大家不要被误导了

反正我是被我误导过,才知道这个错误,坑了我半天编译器一直提醒我signal没有这个属性

5.反馈与建议

第一次写博客,如果以上文章有错误请多多包涵!❥(^_-),有什么不不明白我没说清楚的地方,可以给我留言