👇👇 关注后回复 “进群” ,拉你进程序员交流群 👇👇 作者丨 小sen
来源丨Python之王
「@Author:Runsen」
在Python中,主要采用队列和线程的方法来实现多线程。
队列 队列(queue)
,是先进先出(FIFO, First-In-First-Out)
的线性表,在具体应用中通常用链表或者数组来实现,队列只允许在后端(称为rear)
进行插入操作,在前端(称为front)
进行删除操作,队列的操作方式和堆栈类似,唯一的区别在于队列只允许新数据在后端进行添加。
在Python中队列可以通过内置模块queue
导入,具体导入方法:from queue import Queue
。
queue queue
模块提供了适合多线程编程的先进先出的数据结构,可以用来在生产者和消费者线程之间安全的传递消息或者数据;锁是调用方处理,因此多线程可以安全、方便的使用同一队列实现。
常用属性和方法:
接口 描述 put(x) 入队 get() 出队 empty()
判断队列是否为空 full() 判断队列是否未满 qsize() 队列的当前长度 task_done() 任务结束 join() 等待完成
Queue类实现了一个基本的先进先出容器。使用put方法将元素增加到序列的一端,使用get方法从另一端删除,具体代码如下。
import queue q = queue.Queue()#添加元素 for i in range(5): q.put(i)#删除元素 while not q.empty(): print (q.get())
运行上面的程序,你将会看到下面的输出:
0 1 2 3 4
生产者/消费者模式 我们经常会遇到这样的一个问题,这里有成千上万条数据,每次需要取出其中的一条数据进行处理,那么引入多线程该怎么进行任务分配?
我们可以将数据进行分割然后交给多个线程去跑,因为线程间数据的共享的问题。
它包含两类进程:一种只是用来生产数据,例外一种只是用来消费数据.为了串联他们,通常会采用共享的数据区域,就像一个仓库.生产者产生的数据都放入仓库中并不需要关注消费者的行为,消费者只需要从共享仓库中获取数据,并不需要关心生产者的行为.
# -*- coding:utf-8 -*- # time :2019/4/23 10:13 # Author: Maoli import threadingimport timeimport random MONEY = 0 gLock = threading.Lock()def Procuder () : while True : global MONEY random_money = random.randint(10 ,100 ) gLock.acquire() #加锁 MONEY += random_money gLock.release() #释放锁 print ('生产者%s-生产了%d' % (threading.current_thread,random_money)) time.sleep(0.5 )def Customer () : while True : global MONEY random_money = random.randint(10 ,100 ) if MONEY > random_money: print ('消费者%s-消费了:%d' % (threading.current_thread,random_money)) gLock.acquire() MONEY -= random_money gLock.release() else : print ('需要消费的钱为:%d,余额为:%d,' % (random_money,MONEY)) time.sleep(0.5 )def p_c_test () : # 执行3个线程,来当作生产者 for x in range(3 ): th = threading.Thread(target=Procuder) th.start() # 执行3个线程,来当作消费者 for x in range(3 ): th = threading.Thread(target=Customer) th.start()if __name__ == "__main__" : p_c_test()
运行截图如下:
队列实现多线程 在这里我们可以使用队列与线程相结合的方式进行任务分配。在生产消费者模式当中用到的是阻塞型queue。在Python当中,我们最常用的queue就是一个支持多线程场景的阻塞队列
队列线程的思想:首先创建一个全局共享的队列,队列中只存在有限个元素,并将所有的数据逐条加入到队列中,并调用队列的join函数进行等待。之后便可以开启若干线程,线程的任务就是不断的从队列中取数据进行处理就可以了。
# -*- coding:utf-8 -*- # time :2019/4/23 10:35 # Author: Maoli import threading import time import queue# 下面来通过多线程来处理Queue里面的任务: def work(q): while True: if q.empty(): return else : t = q.get() print ("当前线程sleep {} 秒" .format(t)) time.sleep(t) def main(): q = queue.Queue() for i in range(5): q.put(i) # 往队列里生成消息 thread_num = 5 threads = [] for i in range(thread_num): t = threading.Thread(target=work, args=(q,)) # args需要输出的是一个元组,如果只有一个参数,后面加,表示元组,否则会报错 threads.append(t) # 创建5个线程 for i in range(thread_num): threads[i].start() for i in range(thread_num): threads[i].join()if __name__ == "__main__" : start = time.time() main() print ('耗时:' , time.time() - start)
运行上面的程序,你将会看到下面的输出:
当前线程sleep 0 秒 当前线程sleep 1 秒 当前线程sleep 2 秒 当前线程sleep 3 秒 当前线程sleep 4 秒 耗时:4.002955436706543
今天也学到了很多东西呢,明天有什么新知识呢?真期待鸭~如果喜欢文章可以关注我哦~
Reference [1] 传送门~: https://github.com/MaoliRUNsen/runsenlearnpy100
-End-
最近有一些小伙伴,让我帮忙找一些 面试题 资料,于是我翻遍了收藏的 5T 资料后,汇总整理出来,可以说是程序员面试必备!所有资料都整理到网盘了,欢迎下载!
在看点这里 好文分享给更多人↓↓