天天看點

Python線程和程序(下)隊列線程池

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

隊列

Python線程和程式(下)隊列線程池

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還有下面的用法,不說了

Python線程和程式(下)隊列線程池

線程池

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

Python線程和程式(下)隊列線程池

使用的是 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}
任務完成
           

複制

對于程序和線程就到這裡,使用程序和線程,就是在爬蟲中,可以提高爬蟲速度,就沒了。