上文鎖能解決變量的共享的問題,但是不常見,鎖住别人幹嘛,咱們不如來好好的排下隊。這樣就不會死鎖了,其實queue是自帶鎖。
隊列

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}
任務完成
複制
對于程序和線程就到這裡,使用程序和線程,就是在爬蟲中,可以提高爬蟲速度,就沒了。