对于IO密集型任务,很适合用线程池来处理消息,具体思路如下:
1、创建一个Queue队列
import Queue
queue = Queue.Queue()
2、写一个类,继承线程类,重写run方法处理队列中方法和参数,由于queue是线程安全的,因此这块不必加锁;同时,创建一个线程池:
from threading import Thread
for i in range(thread_num):
debug_logger.info("开启第%s个处理线程" % i)
thread = ThreadManger(queue)
thread.start()
class ThreadManger(Thread):
def __init__(self, queue):
super(ThreadManger, self).__init__()
self.queue = queue
def run(self):
while True:
if self.queue.qsize() > 0:
method, para = self.queue.get(timeout=5.0)
method(para)
self.queue.task_done()
3、将要处理的参数和处理这个参数的方法放进这个队列里,注意将参数和方法组成个元组放进去,这块也可以做成多线程,使用上面创建的queue就行
queue.put((method, parament))
4、这个时候一个简单的线程池就做好了,当队列是空的时候,线程池从queue取不到东西但线程不会结束,一旦有新的内容放到了queue中,线程池会立马取出来并处理掉
5、线程池大小,对于IO密集型的任务,假如cpu处理时间是0.5s,IO时间是1.5s,那线程池的个数为((1.5+0.5)/0.5)*核数+1
6、对于计算密集型的任务,由于GIL导致任何时候只能有一个线程在执行,所以就不要搞并发了,由于线程的切换耗费的时间会导致执行起来比单线程还慢
7、对于分布式任务,可以考虑使用mq,比如kafka或者rabbitmq