7

मैं पायथन 2.7 का उपयोग कर जीए पर एक ऐप विकसित कर रहा था, एक एजेक्स कॉल एपीआई से कुछ डेटा अनुरोध करता है, एक अनुरोध में ~ 200 एमएस लग सकता है, हालांकि जब मैं दो ब्राउज़र खोलता हूं और दो बनाता हूं बहुत ही घंटों में अनुरोध करते हैं कि वे उसमें से दो गुना अधिक लेते हैं, मैंने सबकुछ थ्रेड में डालने की कोशिश की है लेकिन यह काम नहीं कर रहा है .. (यह तब होता है जब ऐप ऑनलाइन होता है, न केवल dev-server पर)पायथन में समांतरता सही काम नहीं कर रही है

तो मैं इस साधारण परीक्षण लिखा था कि अगर यह सामान्य रूप में अजगर में एक समस्या है (एक व्यस्त प्रतीक्षा के मामले में) देखने के लिए यहाँ कोड और परिणाम है,:,

def work(): 
    t = datetime.now() 
    print threading.currentThread(), t 
    i = 0 
    while i < 100000000: 
     i+=1 
    t2 = datetime.now() 
    print threading.currentThread(), t2, t2-t 

if __name__ == '__main__': 
    print "single threaded:" 
    t1 = threading.Thread(target=work) 
    t1.start() 
    t1.join() 

    print "multi threaded:" 
    t1 = threading.Thread(target=work) 
    t1.start() 
    t2 = threading.Thread(target=work) 
    t2.start() 
    t1.join() 
    t2.join() 

पर मैक ओएस एक्स परिणाम सी अयस्क i7 (4 कोर, 8 धागे), पायथन 2.7:

single threaded: 
<Thread(Thread-1, started 4315942912)> 2011-12-06 15:38:07.763146 
<Thread(Thread-1, started 4315942912)> 2011-12-06 15:38:13.091614 0:00:05.328468 

multi threaded: 
<Thread(Thread-2, started 4315942912)> 2011-12-06 15:38:13.091952 
<Thread(Thread-3, started 4323282944)> 2011-12-06 15:38:13.102250 
<Thread(Thread-3, started 4323282944)> 2011-12-06 15:38:29.221050 0:00:16.118800 
<Thread(Thread-2, started 4315942912)> 2011-12-06 15:38:29.237512 0:00:16.145560 

यह बहुत चौंकाने वाला है !! यदि एक धागा को ऐसा करने में 5 सेकंड लगेंगे .. मैंने सोचा था कि एक ही समय में दो धागे शुरू करने के लिए दोनों कार्यों को पूरा करने के लिए एक ही समय लगेगा, लेकिन यह लगभग तीन गुना लेता है .. यह पूरे थ्रेडिंग विचार को बेकार बनाता है, जैसा कि अनुक्रमिक रूप से उन्हें करना तेज़ होगा!

क्या मैं यहाँ याद आ रही है ..

+3

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

+2

आपका बेंचमार्क खराब डिजाइन किया गया है।आपका वास्तविक उपयोग केस आईओ-बाउंड होगा, सीपीयू-बाध्य नहीं। पाइथन का जीआईएल प्रत्येक मामले में काफी अलग व्यवहार करता है। आपके वास्तविक उपयोग मामले में थ्रेडिंग * आपके लिए ठीक काम करना चाहिए। – zeekay

+1

@ g.d.d.c। मल्टीप्रोसेसिंग GAE – bpgergo

उत्तर

9

David Beazley gave a talk PyCon 2010 पर इस मुद्दे को दूसरों पहले ही कहा गया है, कुछ कार्यों के लिए, किसी एकल थ्रेड द्वारा किया जाता एक ही काम के लिए की तुलना में धीमी प्रदर्शन प्राप्त हो सकता विशेष रूप से एकाधिक कोर के साथ सूत्रण का उपयोग कर के बारे में। समस्या, Beazley पाया, कई कोर एक "GIL battle" होने के साथ करना था:

enter image description here

जीआईएल विवाद से बचने के लिए आप अलग धागे के बजाय पृथक प्रक्रियाओं में चल कार्यों होने बेहतर परिणाम प्राप्त कर सकते हैं। multiprocessing मॉड्यूल ऐसा करने का एक सुविधाजनक तरीका प्रदान करता है, विशेष रूप से चूंकि मल्टीप्रोसेसिंग एपीआई थ्रेडिंग एपीआई के समान ही है।

import multiprocessing as mp 
import datetime as dt 
def work(): 
    t = dt.datetime.now() 
    print mp.current_process().name, t 
    i = 0 
    while i < 100000000: 
     i+=1 
    t2 = dt.datetime.now() 
    print mp.current_process().name, t2, t2-t 

if __name__ == '__main__': 
    print "single process:" 
    t1 = mp.Process(target=work) 
    t1.start() 
    t1.join() 

    print "multi process:" 
    t1 = mp.Process(target=work) 
    t1.start() 
    t2 = mp.Process(target=work) 
    t2.start() 
    t1.join() 
    t2.join() 

पैदावार

single process: 
Process-1 2011-12-06 12:34:20.611526 
Process-1 2011-12-06 12:34:28.494831 0:00:07.883305 
multi process: 
Process-3 2011-12-06 12:34:28.497895 
Process-2 2011-12-06 12:34:28.503433 
Process-2 2011-12-06 12:34:36.458354 0:00:07.954921 
Process-3 2011-12-06 12:34:36.546656 0:00:08.048761 

पी एस। जैसा कि ज़ीके ने टिप्पणियों में बताया, जीआईएल युद्ध सीपीयू-बाध्य कार्यों के लिए केवल गंभीर है। यह आईओ-बाध्य कार्यों के लिए एक समस्या नहीं होनी चाहिए।

+0

क्या यह व्यवहार पायथन के लिए विशिष्ट है? और यदि हां, तो क्यों? –

+1

जीआईएल पायथन के लिए विशिष्ट है, और इसलिए "जीआईएल लड़ाइयों" जीआईएल के लिए विशिष्ट हैं। मुझे यकीन नहीं है कि कुछ अन्य भाषाओं में ऐसा कुछ हो सकता है। – unutbu

4

CPython दुभाषिया एक से अधिक थ्रेड को चलाने के लिए अनुमति नहीं दी जाएगी। जीआईएल http://wiki.python.org/moin/GlobalInterpreterLock

के बारे में पढ़ें तो कुछ कार्यों को सीपीथॉन में धागे के साथ एक कुशल तरीके से समवर्ती रूप से नहीं किया जा सकता है।

यदि आप GAE में समानांतर चीजें करना चाहते हैं, तो उन्हें अलग-अलग अनुरोधों के साथ समानांतर प्रारंभ करें।

इसके अलावा, आप अजगर समानांतर विकी http://wiki.python.org/moin/ParallelProcessing

1

मैं कहाँ समय जा रहा है पर विचार करेंगे करने के लिए संपर्क कर सकते हैं। मान लीजिए, उदाहरण के लिए, सर्वर केवल 200ms प्रत्येक प्रश्न का उत्तर दे सकता है। फिर ऐसा कुछ भी नहीं है जो आप कर सकते हैं, आपको केवल हर 200ms में एक जवाब मिलेगा क्योंकि यह सब सर्वर आपको प्रदान कर सकता है।

+0

अपना कोड देखें। वह 'डेटाटाइम' कह रहा है, सर्वर से संचार नहीं कर रहा है। –

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