Python線程和進程(下)
- 2020 年 4 月 10 日
- 筆記
隊列

queue是python的標準庫,俗稱隊列.可以直接import引用,在python2.x中,模塊名為Queue。python3是小寫的queue即可
在python中,多個線程之間的數據是共享的,多個線程進行數據交換的時候,不能夠保證數據的安全性和一致性,所以當多個線程需要進行數據交換的時候,隊列就出現了,隊列可以完美解決線程間的數據交換,保證線程間數據的安全性和一致性(簡單的來說就是多線程需要加鎖,很可能會造成死鎖,而queue自帶鎖。所以多線程結合queue會好的很多。
導入:from queue import Queue
我們還是先看一個案例。queue 就是一個put和get兩個操作,一個走開一個進入。
import time from queue import Queue from threading import Thread from random import randint # 3個隊列 my_queue = Queue(3) def f1(my_queus): for i in range(3): time.sleep(1) num = randint(0,10) print(num) my_queue.put(num) def f2(my_queus): for i in range(3): time.sleep(1) num = my_queue.get() print(num) t1 = Thread(target=f1,args=(my_queue,)) t2 = Thread(target=f2,args=(my_queue,)) t1.start() t2.start() t1.join() t2.join()
執行一下,randint是隨機在0-10取一個數。
10 10 3 3 5 5
這樣就是進一個出一個。
queue還有下面的用法,不說了

線程池
線程多了,是不是要給一個池放在一起比較好,所以 線程池就出來了。這樣有任務了,我找一個線程來幹活。

使用的是 multiprocessing這個標準庫,ThreadPool這個類比之前的Thread這個類多了Pool。
來看demo,用這個ThreadPool。ThreadPool(3)就是在線程池中有3個線程,apply_async就是分配任務,傳入的是一個函數
from multiprocessing.pool import ThreadPool import time def hello(name): print('hello,{}'.format(name)) time.sleep(2) print('Bye') t = ThreadPool(3) for i in range(3): t.apply_async(hello,args=(i,)) t.close() t.join()
我們來運行下
OUT: 幾乎一起完成 hello,0 hello,1 hello,2 幾乎一起完成 Bye Bye Bye
三個線程一起幹活,每一個線程完成我們的hello任務,最後一起完成了。
上面我們使用的for i in range的方法執行任務,因為任務相同,傳入的參數也相同。
我們再看最後一個,傳入*args, **kwargs參數
from multiprocessing.pool import ThreadPool import time pool = ThreadPool(2) def task1(): time.sleep(1) print("任務1完成") def task2(*args,**kwargs): time.sleep(1) print("任務2完成:",args,kwargs) pool.apply_async(task1) pool.apply_async(task2,args=(1,2),kwds={'a':1,'b':2}) print("任務提交完成") pool.close() pool.join() print("任務完成")
執行如下:
任務提交完成 任務1完成 任務2完成:(1, 2) {'a': 1, 'b': 2} 任務完成
對於進程和線程就到這裡,使用進程和線程,就是在爬蟲中,可以提高爬蟲速度,就沒了。