2011-12-30 13 views
19

मैं प्रक्रियाओं के समूह को चलाने के लिए मल्टीप्रोसेसिंग पूल का उपयोग करने का प्रयास कर रहा हूं, जिनमें से प्रत्येक ग्रीनलेट्स का एक गेवेन पूल चलाएगा। इसका कारण यह है कि बहुत सी नेटवर्क गतिविधि है, लेकिन बहुत सी सीपीयू गतिविधि भी है, इसलिए मेरी बैंडविड्थ और मेरे सभी सीपीयू कोर को अधिकतम करने के लिए, मुझे कई प्रक्रियाओं और गीवेंट की एसिंक बंदर पैचिंग की आवश्यकता है। मैं एक कतार बनाने के लिए मल्टीप्रोसेसिंग के प्रबंधक का उपयोग कर रहा हूं जो प्रक्रियाओं को संसाधित करने के लिए प्रक्रियाओं तक पहुंच जाएगा।गीवेंट बंदरगाहिंग ब्रेकिंग मल्टीप्रोसेसिंग

Traceback (most recent call last): 
    File "multimonkeytest.py", line 7, in <module> 
    q = manager.Queue() 
    File "/usr/local/Cellar/python/2.7.2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/managers.py", line 667, in temp 
    token, exp = self._create(typeid, *args, **kwds) 
    File "/usr/local/Cellar/python/2.7.2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/managers.py", line 565, in _create 
    conn = self._Client(self._address, authkey=self._authkey) 
    File "/usr/local/Cellar/python/2.7.2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/connection.py", line 175, in Client 
    answer_challenge(c, authkey) 
    File "/usr/local/Cellar/python/2.7.2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/connection.py", line 409, in answer_challenge 
    message = connection.recv_bytes(256)   # reject large message 
IOError: [Errno 35] Resource temporarily unavailable 

मेरा मानना ​​है कि यह सामान्य सॉकेट के व्यवहार के बीच कुछ अंतर के कारण होना चाहिए:

import multiprocessing 

from gevent import monkey 
monkey.patch_all(thread=False) 

manager = multiprocessing.Manager() 
q = manager.Queue() 

यहाँ अपवाद यह उत्पादन होता है:

यहाँ कोड का एक सरलीकृत टुकड़ा है मॉड्यूल और गीवेंट सॉकेट मॉड्यूल।

यदि मैं उपप्रोसेसर के भीतर बंदरगाह करता हूं, तो कतार सफलतापूर्वक बनाई जाती है, लेकिन जब उपप्रोसेस कतार से() प्राप्त करने का प्रयास करता है, तो एक बहुत ही समान अपवाद होता है। Subprocesses में बड़ी संख्या में नेटवर्क अनुरोध करने के कारण सॉकेट को बंदरगाह की आवश्यकता होती है।

>>> gevent.version_info 
(1, 0, 0, 'alpha', 3) 

कोई भी विचार:

gevent का मेरा संस्करण है, जो मेरा मानना ​​है कि नवीनतम है?

+0

संबंधित: http://bugs.python.org/issue6056 – jfs

उत्तर

1

आपका प्रदान की कोड विंडोज पर मेरे लिए काम करता 7.

संपादित करें:

हटाया पिछले जवाब है, मैं एक ही त्रुटि मिल रही है क्योंकि मैं उबंटू 11.10 VPS पर अपने कोड की कोशिश की है, और ।

देखो के Eventlet have this issue too तरह

+0

त्रुटि वास्तव में कोई अनुरोध किए बिना त्रुटि हो रही है, लेकिन मैंने स्थानीय गीवेंट Bottle.py संचालित सर्वर के साथ भी परीक्षण किया है। मुझे पाइथन 2.7 दोनों के साथ ओएस एक्स शेर और उबंटू 11.04 वीपीएस दोनों पर ट्रेसबैक मिल रहा है। आप किस ओएस/पायथन/गीवेंट का उपयोग कर रहे हैं? – user964375

+0

@ user964375, एचएम, उबंटू 11.10 (वीपीएस) पर मुझे एक ही त्रुटि मिल रही है। Win7 पर कोई त्रुटि नहीं। – reclosedev

+0

विंडोज एक्सपी, और कोड पर परीक्षण किया गया, यहां तक ​​कि कुछ समय बाद भी गीवेंट भाग टूट जाता है। मल्टीप्रोसेसिंग मॉड्यूल में एक मुद्दा लगता है। – Martin

16

उपयोग monkey.patch_all(thread=False, socket=False)

मैं एक ऐसी ही स्थिति में एक ही मुद्दे में समाप्त हो गया है और patch_socket() समारोह के तहत gevent/monkey.py में 115 लाइन को यह नीचे ट्रैक किया गया: _socket.socket = socket.socket। इस लाइन पर टिप्पणी करना टूटने से बचाता है।

यह वह जगह है जहां gevent stdlib socket लाइब्रेरी को अपने आप से बदल देता है। multiprocessing.connectionsocket लाइब्रेरी का व्यापक रूप से उपयोग करता है, और जाहिर है इस परिवर्तन के लिए सहिष्णु नहीं है।

विशेष रूप से, आप इसे किसी भी परिदृश्य में देखेंगे जहां आप आयातित मॉड्यूल socket=False सेट किए बिना gevent.monkey.patch_all() कॉल करता है। मेरे मामले में यह grequests था जिसने ऐसा किया, और मुझे इस त्रुटि को ठीक करने के लिए सॉकेट मॉड्यूल के पैचिंग को ओवरराइड करना पड़ा।

+0

क्या मैं सॉकेट पैचिंग के बिना गीवेंट के साथ अनुरोध लाइब्रेरी का उपयोग कर सकता हूं? –

9

भूगर्भ के संदर्भ में मल्टीप्रोसेसिंग का उपयोग दुर्भाग्य से समस्याओं को उठाने के लिए जाना जाता है। हालांकि, आपका तर्क उचित है ("बहुत सारी नेटवर्क गतिविधि, लेकिन बहुत सी सीपीयू गतिविधि")। यदि आप चाहें, तो http://gehrcke.de/gipc पर एक नज़र डालें। यह मुख्य रूप से आपके उपयोग के मामले के लिए डिज़ाइन किया गया है। जीआईपीसी के साथ, आप आसानी से कुछ पूरी तरह से भू-जागरूक बाल प्रक्रियाओं को जन्म दे सकते हैं और उन्हें एक-दूसरे से और/या माता-पिता के साथ पाइप के माध्यम से सहकारी रूप से बात करने देते हैं।

यदि आपके पास विशिष्ट प्रश्न हैं, तो आप मेरे पास वापस आने के लिए स्वागत करते हैं।

+4

मुझे व्यक्तिगत रूप से लगता है कि यह विचारहीन बंदर पैचिंग है जो समस्याग्रस्त है। भूगर्भ का उपयोग करने वाली कुछ भी चीज़ों को तोड़ने के बारे में एक बहुत बड़ी चेतावनी संकेत के साथ आना चाहिए। औसत प्रोग्रामर जिसने अभी तक gevent-multiprocessing असंगतता के इस विशेष quirk का सामना नहीं किया है (सही ढंग से) मान लें कि gevent stdlib सुविधाओं को तोड़ नहीं है। यह बिल्कुल स्पष्ट नहीं है कि गीवेंट आईपीसी कार्यों को पैच नहीं करता है (जो करने योग्य है) जब यह सॉकेट को पैच करता है। –

+0

मैंने जीआईपीसी दृष्टिकोण की कोशिश की। चूंकि यह कतार वस्तु को याद करता है, इसलिए पाइप का उपयोग करके वैकल्पिक कार्यान्वयन बहुत ही गड़बड़ कर दिया गया था। इसके बजाय 'नाक-gevented-multiprocess' मॉड्यूल देखें – ddotsenko

2

यदि आप मूल कतार का उपयोग करेंगे, तो आप सामान्य रूप से बंदर पैच सॉकेट के साथ भी काम करेंगे।

import multiprocessing 

from gevent import monkey 
monkey.patch_all(thread=False) 

q= multiprocessing.Queue() 
1

एक स्थानापन्न के नाक मल्टीप्रोसेस प्लगइन लिखा - यह एक पागल Gevent आधारित पैचिंग के सभी प्रकार के साथ अच्छी तरह से खेलना चाहिए।

https://pypi.python.org/pypi/nose-gevented-multiprocess/

https://github.com/dvdotsenko/nose_gevent_multiprocess

    कार्यकर्ता प्रक्रियाओं के लिए सादे subprocess.popen को multiprocess.fork से
  • स्विच (फिक्स मॉड्यूल स्तरीय ग़लती से मेरे लिए वस्तुओं मुद्दों साझा)
  • से अधिक JSON-RPC को multiprocess.Queue से स्विचड मास्टर-टू-क्लाइंट आरपीसी
  • के लिए HTTP अब यह सैद्धांतिक रूप से कई मशीनों को परीक्षणों को वितरित करने की अनुमति दे सकता है
संबंधित मुद्दे