Python-進程-進程池-原理

 

 進程python

  資源集合,調度和分配資源,說到進程就不得不提到線程,線程和進程是密不可分,進程申請了資源,但真正使用資源的是線程,其實本質上相似面向對象的思想,面向對象把數據和數據的操做封裝在一個類中,進程把資源和對資源的操做封裝在進程中,其實進程本質上是對資源的封裝,那就比對進程和線程的區別來認識進程:算法

  1. 進程是資源容器,真正使用資源的是線程,進程能夠申請並擁有本身獨立資源但線程不能,線程只能使用進程已有的資源安全

  2. 進程在CPU上執行體如今線程,一個進程至少有一個主線程,能夠有0個或者多個子線程數據結構

  3. 從粒度角度看,進程粒度遠遠比線程大,進程粒度比線程小,也就是切換進程消耗遠比線程切換大app

  4. 線程是操做系統調度的最小單位,對於IO操做進程和線程差異不大,進程和線程均可以競爭CPU資源,歸根到本質上是線程在競爭CPU資源async

  5. 進程與進程之間是資源徹底隔離,也就是說不可互相訪問函數

北門吹雪: http://www.cnblogs.com/2bjiujiu/性能

 

Python進程模塊  multiprocessingspa

  # 這個模塊的接口和線程模塊threading一致操作系統

 

多進程實例過程:

  1. 實例進程

  2. 啓動子進程

  3. 等待子進程結束

import multiprocessing


def add(end, name):
    total = 0
    for i in range(end+1):
        total += i
    print(name)
    return total


if __name__ == '__main__':
    # 實例子進程
    ps = multiprocessing.Process(target=add, args=(100, "北門吹雪"), name="北門吹雪")
    # 啓動子進程
    ps.start()
    # 等待子進程結束
    ps.join()

  

進程池      Pool

  # 接口和線程池一致,能夠獲取進程狀態,如子進程執行結果、否準備、是否執行成功、等待子進程執行完成

  1. 實例進程池,須要傳遞進程池數量

  2. 添加子進程到進程池中

  3. 先關閉Pool,禁止進程池再接收任務

  4. 等待進程池中進程完成

  6. 關閉進程池

import multiprocessing


def add(end, name, blog):
    total = 0
    for i in range(end+1):
        total += i
    print(name, total, blog)
    return total


if __name__ == '__main__':
    # 實例子進程,和CPU數量一致
    ps_pool = multiprocessing.Pool(multiprocessing.cpu_count())
    # 提交任務,得到返回進程對象對象, 可在此提交多個進程
    r = ps_pool.apply_async(func=add, args=(100, "北門吹雪", "https://www.cnblogs.com/2bjiujiu/"))
    # 獲取執行結果,狀態信息
    print(r.get())
    # print(r.wait())
    print(r.ready())
    print(r.successful())
    # 關閉線程池
    ps_pool.close()
    # 等待子線程完成
    ps_pool.join()

  7. 進程池獲取子進程狀態

     執行結果    .get

     是否就緒    .ready

     是否執行成功  .successful

     等待子進程   .wait

  8. 進程池imap方法, 特色是進程函數名不變,改變的傳遞進去的參數,結果是進程返回的結果,有前後順序

import multiprocessing


def add(info):
    end = info[0]
    name = info[1]
    blog = info[2]
    total = 0
    for i in range(end+1):
        total += i
    print(end, name, blog)
    return total


if __name__ == '__main__':
    # 實例子進程,和CPU數量一致
    ps_pool = multiprocessing.Pool(multiprocessing.cpu_count())

    # imap方式
    info = [(100, "北門吹雪", "https://www.cnblogs.com/2bjiujiu/"), (200, "北門吹雪", "https://www.cnblogs.com/2bjiujiu/")]
    # imap方式
    for total in ps_pool.imap(add, info):
        print(total)

 北_門_吹_雪:http://www.cnblogs.com/2bjiujiu/ 

 

進程之間通訊機制

  # 本質上是經過共享內存塊實現通訊

  1. 多進程Queue

import multiprocessing


def add(ps_queue, end, name, blog):
    total = 0
    for i in range(end+1):
        total += i
    print(name, blog)
    ps_queue.put(total)


if __name__ == '__main__':
    # 實例隊列
    ps_queue = multiprocessing.Queue()
    # 實例子進程
    ps = multiprocessing.Process(target=add, args=(ps_queue, 100, "北門吹雪", "https://www.cnblogs.com/2bjiujiu/"), name="北門吹雪")
    # 啓動子進程
    ps.start()
    # 等待子進程結束
    ps.join()
    # 從Queue中取值
    print(ps_queue.get())

  2. 管道  Pipe,只適於兩個進程中通訊,性能優於Queue

import multiprocessing


def add(phone_one, end, name, blog):
    total = 0
    for i in range(end+1):
        total += i
    print(name, blog)
    # 發送數據,固然也能夠接收
    phone_one.send(total)


if __name__ == '__main__':
    # 實例管道, 相似打電話
    phone_one, phone_two = multiprocessing.Pipe()
    
    # 實例子進程
    ps = multiprocessing.Process(target=add, args=(phone_one, 100, "北門吹雪", "https://www.cnblogs.com/2bjiujiu/"), name="北門吹雪")
    # 啓動子進程
    ps.start()
    # 等待子進程結束
    ps.join()
    
    # Pipe中取值
    print(phone_two.recv())

  3. 共享內存  Manager 包含Python基本數據結構 

import multiprocessing
from multiprocessing import Manager


def add(share_list, end, name, blog):
    total = 0
    for i in range(end+1):
        total += i
    print(name, blog)
    # 添加數據
    share_list.append(total)
    share_list.append(name)
    share_list.append(blog)


if __name__ == '__main__':
    # 實例共享內存對象
    share_memory = multiprocessing.Manager()
    # 實例list數據類型,固然除了list包括Python基本數據結構
    share_list = share_memory.list()

    # 實例子進程
    ps = multiprocessing.Process(target=add, args=(share_list, 100, "北門吹雪", "https://www.cnblogs.com/2bjiujiu/"), name="北門吹雪")
    # 啓動子進程
    ps.start()
    # 等待子進程結束
    ps.join()

    # 從共享對象中取值
    print(share_list)

 北_門_吹_雪:http://www.cnblogs.com/2bjiujiu/  

 

計算機資源:

  1. 內存、磁盤、CPU、網卡這4個是計算機核心資源

  2. 資源是稀缺的,須要競爭計算機資源

  3. 進程操做系統調度分配資源的單位,每一個應用至少有一個進程

  4. 進程是競爭計算機資源的單位,CPU能夠在不一樣的應用程序中切換,這個時間很是短暫,宏觀上是並行,這個理念在在單核上,多核CPU能夠並行執行多個進程

  5. 進程調度最核心的功能,操做系統會有本身算法,決定進程是否掛起,進程和線程的切換開銷很是大,將CPU資源消耗在進程和線程切換上,時間片,頻繁切換和保存進程上下文消耗CPU資源

 北_門_吹_雪:http://www.cnblogs.com/2bjiujiu/

 

經驗:

  1. 進程和線程都能競爭CPU資源,而且線程包含在進程中,同時存在又同時消亡(這裏說主進程和主線程),進程和線程邊界不清晰,這讓進程和線程概念更加難以理清

  2. 進程和線程在邏輯上由很是多的類似點,如實例方式、啓動方式、堵塞方式、池的概念、鎖的概念,線程更像縮小版進程,但不是進程,包含在進程中只能使用進程分配已經有的資源

  3. 進程與進程之間資源隔離,不可互相訪問,線程之間只能訪問各自進程中的資源,並非廣義上的能夠互相訪問資源

  4. 進程用面向對象的語義來講,把資源和對資源的操做封裝在一個進程中

  5. 進程切換消耗遠大於線程,但爲什麼仍是須要進程,由於進程很像靜態資源,使用靜態資源效率上遠比動態資源來的效率高,通常進程數量和CPU總核心數一致,但仍是須要考慮安全冗餘,不要把全部CPU跑滿

 北_門_吹_雪:http://www.cnblogs.com/2bjiujiu/

相關文章
相關標籤/搜索