【Python爬虫学习笔记11】Queue线程安全队列和GIL全局解释器锁
Queue線程安全隊(duì)列
在Python多線程編程中,雖然threading模塊為我們提供了Lock類和Condition類借助鎖機(jī)制來處理線程并發(fā)執(zhí)行,但在實(shí)際開發(fā)中使用加鎖和釋放鎖仍是一個(gè)經(jīng)常性的且較為繁瑣的過程。因此,Python中又為我們提供了一個(gè)使用起來更為簡單的模塊——queue模塊。
queue模塊是一個(gè)線程安全的模塊(線程安全——即不存在共享變量訪問沖突問題),該模塊提供了同步的、線程安全的隊(duì)列類,包括FIFO(先進(jìn)先出)隊(duì)列Queue以及LIFO(后進(jìn)先出)隊(duì)列LifoQueue。這些隊(duì)列都已經(jīng)實(shí)現(xiàn)了鎖的原子操作(即要么不做,要么都做完),可以方便地在多線程中直接使用,實(shí)現(xiàn)線程間的同步。
其相關(guān)函數(shù)如下:
1.Queue(maxsize)/LifoQueue(maxsize):創(chuàng)建并初始化一個(gè)大小為maxsize的先進(jìn)先出/后進(jìn)先出的隊(duì)列。
2.qsize():返回隊(duì)列當(dāng)前以存放數(shù)據(jù)的大小。
3.empty():判斷隊(duì)列是否為空。
4.full():判斷隊(duì)列是否滿了。
5.get():從隊(duì)列中取一個(gè)隊(duì)首數(shù)據(jù)。
6.put(data):將一個(gè)數(shù)據(jù)放到隊(duì)列中。
具體的使用示例如下:
##queue模塊的簡單使用示例 from queue import Queue# 初始化隊(duì)列 q = Queue(7)# 判斷隊(duì)列是否為空 print(q.empty()) #True# 存放數(shù)據(jù) for i in range(5):q.put(i)# 輸出當(dāng)前隊(duì)列大小 print(q.qsize()) #5# 判斷隊(duì)列是否為滿 print(q.full()) #False# 依次取出隊(duì)列元素并以列表形式輸出 print([q.get() for x in range(q.qsize())]) #[0,1,2,3,4] print(q.empty()) #True其實(shí)在get()方法中,還可以設(shè)置一個(gè)參數(shù)block,其代表當(dāng)隊(duì)列中沒有數(shù)據(jù)時(shí)應(yīng)采取的操作,默認(rèn)值為True表示持續(xù)等待,如果設(shè)置為Flase則當(dāng)沒有數(shù)據(jù)時(shí)拋出Empty異常。
## 設(shè)置get()方法參數(shù)block from queue import Queue,Emptyq = Queue(3) for i in range(2):q.put(i)elements = [q.get() for x in range(q.qsize())]try:x = q.get(block=False) except Empty:print('The queue is empty.') """ Output:The queue is empty. """GIL全局解釋器鎖
首先,我們先來了解一下Python自帶的解釋器——CPython。CPython解釋器是基于C語言編寫的解釋器,其的多線程機(jī)制并不是一個(gè)正真的多線程,在多核CPU中,Cpython只能利用一核而不能利用多核,即同一時(shí)刻只有一個(gè)線程在執(zhí)行,而表現(xiàn)出多線程是因?yàn)橐粋€(gè)CPU可以在極短的時(shí)間內(nèi)輪轉(zhuǎn)執(zhí)行每一個(gè)線程。
為了保證同一時(shí)刻只有一個(gè)線程在執(zhí)行,在CPython解釋器中有一個(gè)叫做全局解釋器鎖GIL(Global Intepreter Lock)的東西,其主要是用于解決CPython解釋器內(nèi)存管理非線程安全的問題。
而除了CPython解釋器外,還有如下其他的解釋器:
1.Jython:基于Java實(shí)現(xiàn)的Python解釋器,不存在GIL鎖。維基百科:https://en.wikipedia.org/wiki/Jython
2.IronPython:基于.net實(shí)現(xiàn)的Python解釋器,不存在GIL鎖。維基百科:https://en.wikipedia.org/wiki/IronPython
3.PyPy:基于Python實(shí)現(xiàn)的Python解釋器,存在GIL鎖。維基百科:https://en.wikipedia.org/wiki/PyPy
GIL雖然是真正意義上的多線程,但在處理一些IO操作(如文件讀寫和網(wǎng)絡(luò)請求等)時(shí)還是可以提高很多效率的,因此在IO操作上更建議使用多線程機(jī)制;然而在一些CPU計(jì)算操作上用多線程并發(fā)可能反而會(huì)使效率低下,因此在這種情況下更建議使用多進(jìn)程處理。
轉(zhuǎn)載于:https://www.cnblogs.com/Unikfox/p/9708155.html
總結(jié)
以上是生活随笔為你收集整理的【Python爬虫学习笔记11】Queue线程安全队列和GIL全局解释器锁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python基础系列讲解——继承派生和组
- 下一篇: python 打印大话西游