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())
結果如圖:
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")
結果如圖:
4. Pipe模塊
Pipe模塊用來管道操作。返回(conn1, conn2)代表一個管道的兩個端。Pipe方法有duplex參數。
如果duplex參數爲True(默認值),那麼這個管道是全雙工模式,也就是說conn1和conn2均可收發。
duplex爲False,conn1只負責接受消息,conn2只負責發送消息。send和recv方法分別是發送和接受消息的方法。
例如,在全雙工模式下,可以調用conn1.send發送消息,conn1.recv接收消息。如果沒有消息可接收,recv方法會一直阻塞。如果管道已經被關閉,那麼recv方法會拋出EOFError。