方便的行列步队
当我们处理多线程的资源共享时,线程模块的管理会变得很繁芜。我们已经看到了,Python线程模块供应了很多同步原语,包括锁、旗子暗记量、条件变量、事宜等。虽然有这么多的选择,但是利用行列步队可能会是管理线程同步的最佳拍档。行列步队利用起来很随意马虎,由于该模块供应了同步的,安全的对序列,包括FIFO(先入先出)行列步队Queue,LIFO(后入先出)行列步队LifoQueue,和优先级行列步队PriorityQueue.这些行列步队都实现了锁原语,能够在多线程中直策应用。可以利用行列步队来实现线程间的通信:
Queue模块中的常用方法:
Queue.qsize():返回行列步队的大小Queue.empty():如果行列步队为空,返回True,反之FalseQueue.full():如果行列步队满了,返回True,反之FalseQueue.full:与 maxsize 大小对应Queue.get([block[, timeout]]):获取行列步队,timeout等待韶光Queue.get_nowait() :相称Queue.get(False)Queue.put(item):写入行列步队,timeout等待韶光Queue.put_nowait(item):相称Queue.put(item, False)Queue.task_done():在完成一项事情之后,Queue.task_done()函数向任务已经完成的行列步队发送一个旗子暗记Queue.join():实际上意味着等到行列步队为空,再实行别的操作
生产者-消费者模型
利用行列步队实现生产者-消费者模型:
import threadingimport queueimport randomimport time# 创建一个行列步队q = queue.Queue()# 假定商品序号item = 0def produecr(): global item while True: time.sleep(1) item = random.randint(1, 10) # 将一个“商品”推到行列步队中 q.put(item) print('producer {}th gooos append to q.'.format(item)) time.sleep(1)def consumer(): while True: # 在行列步队中删除一个“商品”,并返回该“商品” item = q.get() print(threading.currentThread().getName() + 'consumer get {}th goods from q.'.format(item)) q.task_done()if __name__ == \公众__main__\公众: threads_consumr = [] for i in range(3): t = threading.Thread(target=consumer) t.start() threads_consumr .append(t) thread_producer = threading.Thread(target=produecr) thread_producer.start() q.join() for t in threads_consumr: t.join() thread_producer.join()
运行截图如下:
运行结果
我们可以看到行列步队的利用适用于这种常常发生的场景:比如当有成千上万那的数据亟待处理,然后每次取出一条数据进行处理,如何利用多线程分配处理任务加快处理效率呢?
我们可以将数据进行分割然后交给多个线程去跑,可是这并不是一个明智的做法。在这里我们可以利用行列步队与线程相结合的办法进行任务分配。
可以利用行列步队线程的思想: 首先创建一个全局共享的行列步队,行列步队中只存在有限个元素,并将所有的数据逐条加入到行列步队中,并调用行列步队的join函数进行等待。之后便可以开启多少线程,线程的任务便是不断的从行列步队中取数据进行处理就可以了。