1. 程式人生 > >【Python】Python多程序庫multiprocessing中程序池Pool的返回值順序

【Python】Python多程序庫multiprocessing中程序池Pool的返回值順序

問題起因

最近要將一個文字分割成好幾個topic,每個topic設計一個regressor,各regressor是相互獨立的,最後彙總所有topic的regressor得到總得預測結果。沒錯!類似bagging ensemble!只是我沒有抽樣。文字不大,大概3000行,topic個數為8,於是我寫了一個序列的程式,一個topic算完之後再算另一個topic。可是我在每個topic中用了GridSearchCV來調參,又要選特徵又要調整regressor的引數,導致引數組合一共有1782種。我真是低估了調參的時間,程式跑了一天一夜最後因為忘記import一個庫導致最終的預測精度沒有算出來。後來想到,既然每個topic的預測都是獨立的,那是不是可以並行呢?

Python中的多執行緒與多程序

但是聽聞Python的多執行緒實際上並不能真正利用多核,所以如果使用多執行緒實際上還是在一個核上做併發處理。不過,如果使用多程序就可以真正利用多核,因為各程序之間是相互獨立的,不共享資源,可以在不同的核上執行不同的程序,達到並行的效果。同時在我的問題中,各topic相互獨立,不涉及程序間的通訊,只需最後彙總結果,因此使用多程序是個不錯的選擇。

multiprocessing

一個子程序

multiprocessing模組提供process類實現新建程序。下述程式碼是新建一個子程序。

from multiprocessing import Process

def f(name)
:
print 'hello', name if __name__ == '__main__': p = Process(target=f, args=('bob',)) # 新建一個子程序p,目標函式是f,args是函式f的引數列表 p.start() # 開始執行程序 p.join() # 等待子程序結束
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

上述程式碼中p.join()的意思是等待子程序結束後才執行後續的操作,一般用於程序間通訊。例如有一個讀程序pw和一個寫程序pr,在呼叫pw之前需要先寫pr.join(),表示等待寫程序結束之後才開始執行讀程序。

多個子程序

如果要同時建立多個子程序可以使用multiprocessing.Pool

類。該類可以建立一個程序池,然後在多個核上執行這些程序。

import multiprocessing
import time

def func(msg):
    print multiprocessing.current_process().name + '-' + msg

if __name__ == "__main__":
    pool = multiprocessing.Pool(processes=4) # 建立4個程序
    for i in xrange(10):
        msg = "hello %d" %(i)
        pool.apply_async(func, (msg, ))
    pool.close() # 關閉程序池,表示不能在往程序池中新增程序
    pool.join() # 等待程序池中的所有程序執行完畢,必須在close()之後呼叫
    print "Sub-process(es) done."
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

輸出結果如下:

Sub-process(es) done.
PoolWorker-34-hello 1
PoolWorker-33-hello 0
PoolWorker-35-hello 2
PoolWorker-36-hello 3
PoolWorker-34-hello 7
PoolWorker-33-hello 4
PoolWorker-35-hello 5
PoolWorker-36-hello 6
PoolWorker-33-hello 8
PoolWorker-36-hello 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

上述程式碼中的pool.apply_async()apply()函式的變體,apply_async()apply()的並行版本,apply()apply_async()的阻塞版本,使用apply()主程序會被阻塞直到函式執行結束,所以說是阻塞版本。apply()既是Pool的方法,也是Python內建的函式,兩者等價。可以看到輸出結果並不是按照程式碼for迴圈中的順序輸出的。

多個子程序並返回值

apply_async()本身就可以返回被程序呼叫的函式的返回值。上一個建立多個子程序的程式碼中,如果在函式func中返回一個值,那麼pool.apply_async(func, (msg, ))的結果就是返回pool中所有程序的值的物件(注意是物件,不是值本身)

import multiprocessing
import time

def func(msg):
    return multiprocessing.current_process().name + '-' + msg

if __name__ == "__main__":
    pool = multiprocessing.Pool(processes=4) # 建立4個程序
    results = []
    for i in xrange(10):
        msg = "hello %d" %(i)
        results.append(pool.apply_async(func, (msg, )))
    pool.close() # 關閉程序池,表示不能再往程序池中新增程序,需要在join之前呼叫
    pool.join() # 等待程序池中的所有程序執行完畢
    print ("Sub-process(es) done.")

    for res in results:
        print (res.get())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

上述程式碼輸出結果如下:

Sub-process(es) done.
PoolWorker-37-hello 0
PoolWorker-38-hello 1
PoolWorker-39-hello 2
PoolWorker-40-hello 3
PoolWorker-37-hello 4
PoolWorker-38-hello 5
PoolWorker-39-hello 6
PoolWorker-37-hello 7
PoolWorker-40-hello 8
PoolWorker-38-hello 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

與之前的輸出不同,這次的輸出是有序的。

如果電腦是八核,建立8個程序,在Ubuntu下輸入top命令再按下大鍵盤的1,可以看到每個CPU的使用率是比較平均的,如下圖:

八核CPU使用情況

在system monitor中也可以清楚看到執行多程序前後CPU使用率曲線的差異。 

CPU使用情況

轉自:https://blog.csdn.net/jinping_shi/article/details/52433867

相關推薦

PythonPython程序multiprocessing程序Pool返回順序

問題起因最近要將一個文字分割成好幾個topic,每個topic設計一個regressor,各regressor是相互獨立的,最後彙總所有topic的regressor得到總得預測結果。沒錯!類似bagging ensemble!只是我沒有抽樣。文字不大,大概3000行,top

python-socketServer並發

服務 技術分享 tcp 就會 CP log 服務器 pytho 好用 多線程並發: 修改以上信息即可. 多並發:每來一個請求,服務器就會開一個線程。開啟這個線程和這個額連接進行交互。 多進程並發: ForkingTCPServer在linux上好用。 【pyth

python mysql數據 'latin-1' codec can't encode character錯誤問題解決

處理 tin sql數據庫 clas question ack RM can 意思 UnicodeEncodeError: ‘latin-1‘ codec can‘t encode character "UnicodeEncodeError:‘latin-1‘ co

轉+python為什麽推薦使用進程

文件處理 自動切換 問題 決定 其他 意義 一個 strong 計算 最近在看Python的多線程,經常我們會聽到老手說:“Python下多線程是雞肋,推薦使用多進程!”,但是為什麽這麽說呢? 要知其然,更要知其所以然。所以有了下面的深入研究:

leetcodepython演算法題

859. 親密字串 給定兩個由小寫字母構成的字串 A 和 B ,只要我們可以通過交換 A 中的兩個字母得到與 B 相等的結果,就返回 true ;否則返回 false 

leetcodepython演算法題——簡單難度2

66. 加一 給定一個由整數組成的非空陣列所表示的非負整數,在該數的基礎上加一。 最高位數字存放在陣列的首位, 陣列中每個元素只儲存一個數字。 你可以假設除了整數 0 之外,這個整數不會以零開頭。 示例 1: 輸入: [1,2,3] 輸出: [1,2,4] 解

leetcodepython演算法題——簡單難度1

1. 兩數之和 給定一個整數陣列和一個目標值,找出陣列中和為目標值的兩個數。 你可以假設每個輸入只對應一種答案,且同樣的元素不能被重複利用。 示例: 給定 nums = [2, 7, 11, 15], target = 9 因為 nums[0] + nums[1] = 2

leetcodepython演算法題——簡單難度3

118. 楊輝三角 給定一個非負整數 numRows,生成楊輝三角的前 numRows 行。 在楊輝三角中,每個數是它左上方和右上方的數的和。 示例: 輸入: 5 輸出: [ [1], [1,1], [1,2,1]

pythonpython 常用的安裝

由於每次安裝python都要安裝很多包,因此將包安裝程式碼寫在下面,供以後安裝: pip install numpy pip install scipy pip install pillow pip install tensorflow pip install keras 清理系統垃圾 s

python詳解pandas的pd.merge_ordered與pd.merge_asof

merge_ordered: 函式允許組合時間序列和其他有序資料。 特別是它有一個可選的fill_method關鍵字來填充/插入缺失的資料。 import pandas as pd left = pd.DataFrame({'k': ['K0', 'K1', 'K1'

python詳解pandas的pd.merge函式

本篇詳細說明merge的應用,join 和concatenate的拼接方法的與之相似。 pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False

python詳解pymongo的使用

1、連線mongodb,建立client 傳入 ip 值或者 localhost ,埠是27017 import pymongo from pymongo import MongoClient client = MongoClient() #連線到本地 client = Mong

整理python學習筆記(5)-- pygame的函式和方法整理

PYGAME的方法和官方文件查詢 官方文件 http://www.pygame.org/docs/   模組 簡介 pygame.BufferProxy An array protocol view

7、PythonPython jpype呼叫java類

Python jpype 一、安裝     如果你安裝使用的是python 3.3及以上的版本,這些版本都內建了pip包管理器,你可以使用pip簡單快速的安裝jpype: pip install jpype1 二、呼叫java API 說明:在使用python jpyp

python詳解pandas的df.merge函式

本篇詳細說明merge的應用,join 和concatenate的拼接方法的與之相似。 pd.merge(left, right, how='inner', on=None, left_on=None,

python--Python生成唯一ID的——UUID

原文連結https://www.douban.com/note/69073375/ 本來是要給例項新增唯一標識,想了一個偽隨機的方法: # 我想的偽隨機辦法 # 用時間戳和隨機數來生成唯一數字id import scipy

python離線安裝第三方

Anaconda 搜尋bz2安裝包: https://anaconda.org/ 某些以-C指定源安裝的包可能需要登陸 下載bz2檔案並執行命令: conda install --use-local *.bz2 pip 搜尋whl安裝包:https://pypi.o

專欄 - Python 科學計算NumPy 完整教程

Python 科學計算庫NumPy 完整教程 NumPy 是 Python 在科學計算領域取得成功的關鍵之一,如果你想通過 Python 學習資料科學或者機器學習,就必須學習 NumPy。我認為 NumPy 的功能很強大,而且入門

16python使用turtle繪畫

畫蛇 import turtle def drawSnake(rad, angle, len, neckrad):  #     for i in range(len):         turtle.circle(rad, angle)   # 畫圓 rad:圓半徑 an

python詳解numpy與pandasaxis=0,axis= 1軸的用法

對資料進行操作時,經常需要在橫軸方向或者數軸方向對資料進行操作,這時需要設定引數axis的值: axis = 0 代表對橫軸操作,也就是第0軸; axis = 1 代表對縱軸操作,也就是第1軸;