Python爬蟲 multiprocessing庫應用詳解

Python爬蟲(十)

學習Python爬蟲過程中的心得體會以及知識點的整理,方便我自己查找,也希望可以和大家一起交流。

—— multiprocessing庫應用詳解 ——


multiprocessing庫對應的是進程。
進程和線程的問題點擊詳細教程查看。

1. Process模塊

Process模塊用來創建子進程,可以實現多進程的創建,啓動,關閉等操作。

1.1 構造方法

Process([group [, target [, name [, args [, kwargs]]]]])

p = multiprocessing.Process(target = worker, args = (3,))
  • group: 線程組,目前還沒有實現,庫引用中提示必須是None;
  • target: 要執行的方法;
  • name: 進程名;
  • args/kwargs: 要傳入方法的參數。

1.2 其他方法

  • is_alive():返回進程是否在運行。

    print("p.is_alive:", p.is_alive())
    
  • start():進程準備運行,等待調度。

    p.start()
    
  • run():如果實例進程時未制定傳入target,start()執行默認run()方法。

  • terminate():不管任務是否完成,立即停止工作進程。

  • daemon:將父進程設置爲守護進程,當父進程結束時,子進程也結束。

    p.daemon = True
    

    具體使用方法見multiprocessing庫實踐。

  • name:進程名字。

    print("p.name:", p.name)
    
  • pid:進程號。

    print("p.pid:", p.pid)
    

※最簡單的使用進程的方式:

import multiprocessing
import time

def worker(interval):
    n = 5
    while n > 0:
        print("The time is {0}".format(time.ctime()))
        time.sleep(interval)
        n -= 1

if __name__ == "__main__":
    p = multiprocessing.Process(target = worker, args = (3,))
    p.start()
    print("p.pid:", p.pid)
    print("p.name:", p.name)
    print("p.is_alive:", p.is_alive())

結果如圖:
multiprocessing庫應用詳解

2. Pool模塊

Pool模塊是用來創建管理進程池的,當子進程非常多且需要控制子進程數量時可以使用此模塊。

2.1 構造方法

Pool([processes[, initializer[, initargs[, maxtasksperchild[, context]]]]])

pool = Pool(processes=10)
  • processes :使用的工作進程的數量,如果processes是None那麼使用 os.cpu_count()返回的數量。

  • initializer: 如果initializer是None,那麼每一個工作進程在開始的時候會調用initializer(*initargs)。

  • maxtasksperchild:工作進程退出之前可以完成的任務數,完成後用一個新的工作進程來替代原進程,來讓閒置的資源被釋放。maxtasksperchild默認是None,意味着只要Pool存在工作進程就會一直存活。

  • context: 用在制定工作進程啓動時的上下文,一般使用 multiprocessing.Pool() 或者一個context對象的Pool()方法來創建一個池,兩種方法都適當的設置了context。

2.2 其他方法

  • apply_async(func[, args[, kwds[, callback]]]) :非阻塞的。

  • apply(func[, args[, kwds]]):阻塞的。

  • close():關閉pool,使其不在接受新的任務。

  • terminate():關閉pool,結束工作進程,不在處理未完成的任務。

3. Queue模塊

Queue模塊用來控制進程安全。可以使用Queue實現多進程之間的數據傳遞。

put方法用以插入數據到隊列中,put方法還有兩個可選參數:blocked和timeout。
如果blocked爲True(默認值),並且timeout爲正值,該方法會阻塞timeout指定的時間,直到該隊列有剩餘的空間。如果超時,會拋出Queue.Full異常。
如果blocked爲False,但該Queue已滿,會立即拋出Queue.Full異常。

get方法可以從隊列讀取並且刪除一個元素。同樣,get方法有兩個可選參數:blocked和timeout。
如果blocked爲True(默認值),並且timeout爲正值,那麼在等待時間內沒有取到任何元素,會拋出Queue.Empty異常。
如果blocked爲False,有兩種情況存在,如果Queue有一個值可用,則立即返回該值,否則,如果隊列爲空,則立即拋出Queue.Empty異常。

示例代碼:

import multiprocessing
import time

def writer_proc(q):
    try:
        q.put(1, block = False)
    except:
        pass

def reader_proc(q):
    time.sleep(3)
    try:
        print (q.get(block = False))
    except:
        pass

if __name__ == "__main__":
    q = multiprocessing.Queue()
    writer = multiprocessing.Process(target=writer_proc, args=(q,))
    writer.start()

    reader = multiprocessing.Process(target=reader_proc, args=(q,))
    reader.start()

    reader.join()
    writer.join()
    print("aaa")

結果如圖:
multiprocessing庫應用詳解

4. Pipe模塊

Pipe模塊用來管道操作。返回(conn1, conn2)代表一個管道的兩個端。Pipe方法有duplex參數。

如果duplex參數爲True(默認值),那麼這個管道是全雙工模式,也就是說conn1和conn2均可收發。

duplex爲False,conn1只負責接受消息,conn2只負責發送消息。send和recv方法分別是發送和接受消息的方法。

例如,在全雙工模式下,可以調用conn1.send發送消息,conn1.recv接收消息。如果沒有消息可接收,recv方法會一直阻塞。如果管道已經被關閉,那麼recv方法會拋出EOFError。

multiprocessing庫應用詳解
multiprocessing庫應用詳解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章