2015-04-22 13 views
33

का उपयोग नहीं कर रहा है, मैं भविष्यवाणी मॉडल के लिए ग्रिड खोज चलाने के लिए पाइथन मल्टीप्रोसेसिंग का उपयोग करना चाहता हूं। जब मैं कोर उपयोग को देखता हूं, तो यह हमेशा केवल एक कोर का उपयोग करता प्रतीत होता है। कोई विचार क्या मैं गलत कर रहा हूँ?पायथन मल्टीप्रोसेसिंग एक से अधिक कोर

import multiprocessing 
from sklearn import svm 
import itertools 

#first read some data 
#X will be my feature Numpy 2D array 
#y will be my 1D Numpy array of labels 

#define the grid   
C = [0.1, 1] 
gamma = [0.0] 
params = [C, gamma] 
grid = list(itertools.product(*params)) 
GRID_hx = [] 

def worker(par, grid_list): 
    #define a sklearn model 
    clf = svm.SVC(C=g[0], gamma=g[1],probability=True,random_state=SEED) 
    #run a cross validation function: returns error 
    ll = my_cross_validation_function(X, y, model=clf, n=1, test_size=0.2) 
    print(par, ll) 
    grid_list.append((par, ll)) 


if __name__ == '__main__': 
    manager = multiprocessing.Manager() 
    GRID_hx = manager.list() 
    jobs = [] 
    for g in grid: 
     p = multiprocessing.Process(target=worker, args=(g,GRID_hx)) 
     jobs.append(p) 
     p.start() 
     p.join() 

    print("\n-------------------") 
    print("SORTED LIST") 
    print("-------------------") 
    L = sorted(GRID_hx, key=itemgetter(1)) 
    for l in L[:5]: 
     print l 
+1

एक बार जब आप उसमें शामिल हो जाते हैं, तो आप ग्लोबल इंटरप्रेटर लॉक (जीआईएल) पर भी पढ़ना चाहेंगे। पाइथन एक ही समय में दो धागे पर पायथन कोड निष्पादित नहीं कर सकता है। हालांकि, पाइथन के लिए सी लाइब्रेरी के मामले में numpy की तरह, उन पुस्तकालयों * बहुत computationally गहन कार्यों के दौरान जीआईएल छोड़ने के लिए * चुना * कर सकते हैं। यदि आप कई कोर प्रभावी ढंग से उपयोग करना चाहते हैं, तो सुनिश्चित करें कि आपका अधिकांश काम उन सी पुस्तकालयों में से एक में किया जाता है जो काम करते समय जीआईएल छोड़ देता है। –

+0

नोट: आप शायद प्रत्येक प्रक्रिया को मैन्युअल रूप से बनाने और जुड़ने के बजाय एक ['पूल'] (https://docs.python.org/3/library/multiprocessing.html#multiprocessing.pool.Pool) का उपयोग करना चाहते हैं। बस 'pool.map करें (कार्यकर्ता, args = ज़िप (ग्रिड, [GRID_hx] * लेन (ग्रिड))])' और यह स्वचालित रूप से विभिन्न प्रक्रियाओं (समानांतर में) लॉन्च करेगा और उनसे जुड़ जाएगा। – Bakuriu

+5

@CortAmmon आप जो लिख रहे हैं वह पूरी तरह से अप्रासंगिक है। वह बहु ** प्रसंस्करण ** बहु * थ्रेडिंग * का उपयोग नहीं कर रहा है, इसलिए जीआईएल उस कोड में * किसी भी * भूमिका को सादा नहीं करता है। इसके अलावा: तथ्य यह है कि वह 'थ्रेडिंग' के बजाय 'मल्टीप्रोसेसिंग' का उपयोग कर रहा है, इसका मतलब है कि वह पहले से ही जीआईएल के बारे में जानता है। – Bakuriu

उत्तर

49

आपकी समस्या यह है कि आप तुरंत हर काम में शामिल होने के बाद आप इसे शुरू कर दिया है:

for g in grid: 
    p = multiprocessing.Process(target=worker, args=(g,GRID_hx)) 
    jobs.append(p) 
    p.start() 
    p.join() 

ब्लॉक में शामिल होने तक संबंधित प्रक्रिया काम कर समाप्त हो गया है। इसका मतलब है कि आपका कोड एक बार में केवल एक प्रक्रिया शुरू करता है, यह समाप्त होने तक प्रतीक्षा करता है और फिर अगले शुरू करता है।

सभी प्रक्रियाओं के लिए आदेश समानांतर में चलाने के लिए, आप करने की जरूरत है पहली बार उन्हें शुरू सब और फिर उन सब में शामिल होने:

jobs = [] 
for g in grid: 
    p = multiprocessing.Process(target=worker, args=(g,GRID_hx)) 
    jobs.append(p) 
    p.start() 

for j in jobs: 
    j.join() 

प्रलेखन: link

6

मैं कहना चाहता हूँ:

for g in grid: 
    g.p = multiprocessing.Process(target=worker, args=(g,GRID_hx)) 
    jobs.append(g.p) 
    g.p.start() 
for g in grid: 
    g.p.join() 

वर्तमान में आप एक नौकरी को उत्पन्न करने के रहे हैं, तो के लिए यह, किया जाना तो अगले एक करने के लिए जा waithing।

+0

'p.start()' लाइन 'nameError' को बढ़ाएगी क्योंकि 'p' मौजूद नहीं है। –

6

अनुसार the documentation करने में शामिल होने के() कमांड वर्तमान धागे को निर्दिष्ट थ्रेड रिटर्न तक लॉक करता है। तो आप मूल रूप से प्रत्येक थ्रेड को लूप में शुरू कर रहे हैं और फिर इसे पूरा करने के लिए प्रतीक्षा करें, इससे पहले कि आप अगले पुनरावृत्ति पर जाएं।

मैं लूप के बाहर जुड़ने का सुझाव दूंगा!

संबंधित मुद्दे