Python進程基礎概率以及實現

多進程:

             Python實現多進程的方式主要有兩種,一種方法是使用os模塊中的fork方法,另一種方法是使用multiprocessing模塊,這兩種方法區別在於前者僅使用於Unix/Linux操作系統,對Windows不支持,後者是跨平臺的實現方式,由於現在許多爬蟲程序都是運行在Linux/Unix操作系統上,所以在這都說一下.

  1.   使用os模塊中的fork方式實現多進程

            Python的os模塊封裝了常見的系統調用,其中就有fork方法,fork方法來自於Unix/Linux系統中提供的fork調用,這個方法                比較 特殊,普通方法都是調用一次,返回一次,而fork方法是調用一次,返回兩次,原因在於操作系統講當前進程(父進              程)複製出一份進程(子進程),這兩個進程幾乎完全相同,於是fork方法分別在父進程和子進程中返回,子進程中永遠              返回0,父進程中返回的是子進程的ID,例如:(其中getpid方法獲取當前進程的ID,getppid方法獲取父進程的id)

            

           返回

           

 

    2.使用multiprocessing模塊創建多進程

            multiprocessing模塊提供了一個process類描述一個進程對象,創建子進程時,只需要傳入一個執行函數和函數的參數,即可完成一個process實例的創建,用start()方法啓動進程,用join()方法實現進程間的同步,例如:

import os
from multiprocessing import Process


# 子進程要執行的代碼
def run_proc(name):
    print('name:{},pid:{}'.format(name, os.getpid()))


if __name__ == '__main__':
    print('start pid:{}'.format(os.getpid()))
    for i in range(5):
        p = Process(target=run_proc, args=(str(i),))
        print('process will start')
        p.start()
    p.join()
    print('process end')

    返回:

           start pid:15420
           process will start
           process will start
           process will start
           process will start
           process will start
           name:1,pid:8580
           name:0,pid:3200
           name:2,pid:14520
           name:3,pid:15400
           name:4,pid:15656
           process end

   以上是創建進程的兩種方法,但是如果要啓動大量的子進程,使用進程池批量創建子進程的方式更加常見,以爲當被操作對象數目不大時,可以直接利用multiprocessing中process動態生成多了子進程,如果是上百個,上千個目標,手動去限制進程數量卻又太過繁瑣,這時就需要進程池pool發揮作用了。

3.multiprocessing模塊提供了一個pool類代表進程池對象

            pool可以提供指定數量的進程供用戶調用,默認大小是cpu的的核數,當有新的請求提交到pool中時,如果池還沒有滿,n那麼就會創建一個新的進程用來執行該請求;但如果池中的進程數已經達到規定最大值,那麼該請求就會等待,知道池中有進程結束,纔會創建新的進程來處理它,例如:

from multiprocessing import Pool
import os, time, random


def run_task(name):
    print('task:{},pid:{} is running...'.format(name, os.getpid()))
    time.sleep(random.random() * 3)
    print('task {} end'.format(name))


if __name__ == '__main__':
    print('process {}.'.format(os.getpid()))
    p = Pool(processes=3)
    for i in range(5):
        p.apply_async(run_task, args=(i,))
    print('waiting for all subprocesses done..')
    p.close()
    p.join()
    print('end')

   返回:

  

上述程序先創建了容量爲3的進程池,依次向進程池中添加了5個任務,從運行結果中可以看到雖然添加了5個任務,但是一開始只運行了3個,而且最多運行3個經常,當一個任務結束了,新的任務依次添加進去,任務執行使用的進程依然是原來的進程,這一點通過進程的pid可以看出來。

注意:pool 對象調用join(),方法會等待所有子進程執行完畢,調用join()之前必須調用close(),調用close()之後就不能繼續添加新的process。

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