Python多线程与Queue队列多线程在感官上类似于同时执行多个程序,虽然由于GIL的存在,在Python中无法实现线程的真正并行,但是对于某些场景,多线程仍不失为一个有效的处理方法:

1,不紧急的,无需阻塞主线程的任务,此时可以利用多线程在后台慢慢处理;
2,IO密集型操作,比如文件读写、用户输入和网络请求等,此时多线程可以近似达到甚至优于多进程的表现;

多线程的基本使用不再赘述,以下语法便可轻松实现:

复制代码
1 def task(args1, args2): 2     pass3 4 Thread( 5     target=task, 6     args=(args1, args2) 7 ).start()
复制代码


这里我们重点关注线程通信。

假设有这么一种场景:有一批源数据,指定一个操作系数N,需要分别对其进行与N的加减乘除操作,并将结果汇总。
当然这里的加减乘除只是一种简单处理,在实际的生产环境中,它其实代表了一步较为复杂的业务操作,并包含了较多的IO处理。

自然我们想到可以开启多线程处理,那么紧接着的问题便是:如何划分线程,是根据处理步骤划分,还是根据源数据划分?

对于前者,我们把涉及的业务操作单独划分位一个线程,即有4个线程分别进行加减乘除的操作,显然上一个线程的结果是下一个线程的输入,这类似于流水线操作;

而后者则是把源数据分为若干份,每份启动一个线程进行处理,最终把结果汇总。一般来说,我们推荐第一种方式。因为在一个线程中完成所有的操作不如每步一个线程清晰明了,

尤其是在一些复杂的场景下,会加大单个线程的出错概率和测试难度。

那么我们将开辟4个线程,分别执行加减乘除操作。最后一个除法线程结束则任务完成:

 

复制代码
 1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3  4 from Queue import Queue  5 from threading import Thread  6  7  8 class NumberHandler(object):  9     def __init__(self, n): 10         self.n = n 11 12     def add(self, num): 13         return num + self.n 14 15     def subtract(self, num): 16         return num - self.n 17 18     def multiply(self, num): 19         return num * self.n * self.n 20 21     def divide(self, num): 22         return num / self.n 23 24 25 class ClosableQueue(Queue): 26     SENTINEL = object() 27 28     def close(self): 29         self.put(self.SENTINEL) 30 31     def __iter__(self): 32         while