­

Python線程和進程(下)

  • 2020 年 4 月 10 日
  • 筆記
上文鎖能解決變量的共享的問題,但是不常見,鎖住別人幹嘛,咱們不如來好好的排下隊。這樣就不會死鎖了,其實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}  任務完成  

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