तरीके एक मुड़ आवेदन के लिए मल्टीप्रोसेस आपरेशन का समर्थन करने के लिए की एक संख्या हैं। शुरुआत में जवाब देने का एक महत्वपूर्ण सवाल यह है कि, आप अपने समवर्ती मॉडल की अपेक्षा करते हैं, और आपका एप्लिकेशन साझा राज्य से कैसे संबंधित है।
एक ही प्रक्रिया में मुड़कर आवेदन, समेकन सभी सहकारी (ट्विस्टेड एसिंक्रोनस आई/ओ एपीआई से मदद के साथ) और साझा राज्य कहीं भी रखा जा सकता है एक पाइथन ऑब्जेक्ट जाएगा। आपका एप्लिकेशन कोड यह जानकर चलता है कि, जब तक यह नियंत्रण छोड़ देता है, कुछ और नहीं चलेगा। इसके अतिरिक्त, आपके आवेदन का कोई भी हिस्सा जो साझा राज्य के कुछ हिस्सों तक पहुंचना चाहता है, शायद इतना आसानी से कर सकता है, क्योंकि उस स्थिति को शायद उबाऊ पुरानी पायथन ऑब्जेक्ट में रखा जा सकता है जो एक्सेस करना आसान है।
आप कई प्रक्रियाओं है, भले ही वे चल रहे सभी मुड़-आधारित अनुप्रयोगों रहे हैं, तो आप संगामिति के दो रूपों की है। एक पिछले मामले के समान है - एक विशेष प्रक्रिया के भीतर, समेकन सहकारी है। हालांकि, आपके पास एक नई तरह है, जहां कई प्रक्रियाएं चल रही हैं। आपके प्लेटफॉर्म की प्रक्रिया शेड्यूलर किसी भी समय इन प्रक्रियाओं के बीच निष्पादन स्विच कर सकता है, और इस पर आपका बहुत कम नियंत्रण होता है (साथ ही जब यह होता है तो बहुत कम दृश्यता)। यह अलग-अलग कोरों पर एक साथ चलाने के लिए आपकी दो प्रक्रियाओं को भी शेड्यूल कर सकता है (यह शायद आप जो भी उम्मीद कर रहे हैं)। इसका मतलब यह है कि आप स्थिरता के बारे में कुछ गारंटी खो देते हैं, क्योंकि एक प्रक्रिया को पता नहीं होता कि दूसरी प्रक्रिया कब आ सकती है और कुछ साझा राज्य पर काम करने की कोशिश की जाती है। यह विचार के अन्य महत्वपूर्ण क्षेत्र में जाता है, आप वास्तव में प्रक्रियाओं के बीच राज्य कैसे साझा करेंगे।
एकल प्रक्रिया मॉडल के विपरीत, आप अब किसी भी सुविधाजनक है, आसानी से पहुँचा जहां अपने सभी कोड वहां पहुंच सकते हैं अपने राज्य स्टोर करने के लिए स्थान नहीं हैं। यदि आप इसे एक प्रक्रिया में डालते हैं, तो उस प्रक्रिया में मौजूद सभी कोड इसे सामान्य पायथन ऑब्जेक्ट के रूप में आसानी से एक्सेस कर सकते हैं, लेकिन आपकी किसी अन्य प्रक्रिया में चल रहे किसी भी कोड के पास अब तक आसान पहुंच नहीं है। आपकी प्रक्रियाओं को एक दूसरे के साथ संवाद करने के लिए आपको एक आरपीसी प्रणाली खोजने की आवश्यकता हो सकती है।या, आप अपनी प्रक्रिया को विभाजित कर सकते हैं ताकि प्रत्येक प्रक्रिया केवल उन अनुरोधों को प्राप्त करे जिनके लिए उस प्रक्रिया में संग्रहीत राज्य की आवश्यकता होती है। इसका एक उदाहरण सत्रों के साथ एक वेबसाइट हो सकता है, जहां उपयोगकर्ता के बारे में सभी राज्य अपने सत्र में संग्रहीत होते हैं, और उनके सत्र कुकीज़ द्वारा पहचाने जाते हैं। एक फ्रंट-एंड प्रक्रिया वेब अनुरोध प्राप्त कर सकती है, कुकी का निरीक्षण कर सकती है, उस सत्र के लिए कौन सी बैक-एंड प्रक्रिया ज़िम्मेदार है, और उसके बाद अनुरोध को उस बैक-एंड प्रक्रिया पर अग्रेषित करें। इस योजना का अर्थ है कि बैक-एंड आमतौर पर संवाद करने की आवश्यकता नहीं होती है (जब तक आपका वेब एप्लिकेशन पर्याप्त सरल होता है - यानी, जब तक उपयोगकर्ता एक दूसरे के साथ बातचीत नहीं करते हैं, या साझा डेटा पर काम नहीं करते हैं)।
ध्यान दें कि उस उदाहरण में, एक प्री-फोर्किंग मॉडल उपयुक्त नहीं है। फ्रंट-एंड प्रक्रिया में विशेष रूप से सुनवाई बंदरगाह का स्वामित्व होना चाहिए ताकि वह बैक-एंड प्रक्रिया द्वारा संभाले जाने से पहले सभी आने वाले अनुरोधों का निरीक्षण कर सके।
बेशक, राज्य के प्रबंधन के लिए कई अन्य मॉडल के साथ कई प्रकार के आवेदन हैं। बहु-प्रसंस्करण के लिए सही मॉडल का चयन करने से पहले यह समझने की आवश्यकता होती है कि आपके आवेदन के लिए किस प्रकार की सहमति मिलती है, और आप अपने आवेदन के राज्य को कैसे प्रबंधित कर सकते हैं।
कहा जा रहा है कि ट्विस्ट के बहुत नए संस्करण (इस बिंदु के रूप में रिलीज़ नहीं) के साथ, कई प्रक्रियाओं के बीच एक सुनवाई टीसीपी पोर्ट साझा करना काफी आसान है।
from os import environ
from sys import argv, executable
from socket import AF_INET
from twisted.internet import reactor
from twisted.web.server import Site
from twisted.web.static import File
def main(fd=None):
root = File("/var/www")
factory = Site(root)
if fd is None:
# Create a new listening port and several other processes to help out.
port = reactor.listenTCP(8080, factory)
for i in range(3):
reactor.spawnProcess(
None, executable, [executable, __file__, str(port.fileno())],
childFDs={0: 0, 1: 1, 2: 2, port.fileno(): port.fileno()},
env=environ)
else:
# Another process created the port, just start listening on it.
port = reactor.adoptStreamPort(fd, AF_INET, factory)
reactor.run()
if __name__ == '__main__':
if len(argv) == 1:
main()
else:
main(int(argv[1]))
पुराने संस्करणों के साथ, आप कभी कभी बंदरगाह साझा करने के लिए fork
उपयोग करने के साथ प्राप्त कर सकते हैं: कोड स्निपेट जो एक ही रास्ता है कि आप कुछ नए API का उपयोग हो सकता है यह पूरा करने को दर्शाता है है। बहरहाल, यह नहीं बल्कि त्रुटियों की संभावना है, कुछ प्लेटफार्मों पर विफल रहता है, और मुड़ उपयोग करने के लिए एक समर्थित तरीका नहीं है:
from os import fork
from twisted.internet import reactor
from twisted.web.server import Site
from twisted.web.static import File
def main():
root = File("/var/www")
factory = Site(root)
# Create a new listening port
port = reactor.listenTCP(8080, factory)
# Create a few more processes to also service that port
for i in range(3):
if fork() == 0:
# Proceed immediately onward in the children.
# The parent will continue the for loop.
break
reactor.run()
if __name__ == '__main__':
main()
यह कांटा, के सामान्य व्यवहार की वजह से काम करता है जहां नव निर्मित प्रक्रिया (बच्चे) मूल प्रक्रिया (अभिभावक) से सभी स्मृति और फ़ाइल वर्णनकर्ताओं को विरासत में मिला है। चूंकि प्रक्रियाओं को अन्यथा अलग किया जाता है, इसलिए दो प्रक्रियाएं एक दूसरे के साथ हस्तक्षेप नहीं करती हैं, कम से कम जहां तक वे पाइथन कोड निष्पादित कर रहे हैं। चूंकि फ़ाइल डिस्क्रिप्टर विरासत में हैं, या तो माता-पिता या कोई भी बच्चे पोर्ट पर कनेक्शन स्वीकार कर सकता है।
HTTP अनुरोधों को अग्रेषित करने के बाद से यह एक आसान काम है, मुझे संदेह है कि आप इन तकनीकों में से किसी एक का उपयोग करके प्रदर्शन सुधार में अधिक ध्यान देंगे। पूर्व प्रॉक्सीइंग की तुलना में थोड़ा अच्छा है, क्योंकि यह आपके तैनाती को सरल बनाता है और गैर-HTTP अनुप्रयोगों के लिए अधिक आसानी से काम करता है। उत्तरार्द्ध शायद स्वीकार्य होने के लायक होने की ज़िम्मेदारी अधिक है।
जीन-पॉल, सबसे पहले, इस विस्तृत उत्तर के लिए धन्यवाद। बहुत सराहना की! मेरा आवेदन बहुत आसान है, प्रक्रियाओं के बीच कोई साझा स्थिति नहीं है, संभालने के लिए कोई सत्र नहीं है, प्रक्रियाओं के बीच संचार की आवश्यकता नहीं है। मेरा कार्य समांतर कंप्यूटिंग के लिए उपयुक्त है, और (सिद्धांत रूप में) मैं वास्तव में डॉन ' टी मेरी देखभाल करता है अगर मेरी प्रक्रियाएं एक ही सर्वर पर चलती हैं, या प्रत्येक प्रक्रिया अपनी मशीन पर चलती है। बहु-कोर CPUs के साथ बड़े सर्वर का उपयोग करने का कारण यह है कि अमेज़ॅन उन पर बेहतर I/O प्रदर्शन प्रदान करता है। –
ने थोड़ा सा ट्विंक ट्रंक स्रोत (posixbase.py, tcp.py) ब्राउज़ किया, और ऐसा लगता है कि पूर्ववर्ती सॉकेट का पुन: उपयोग करने के लिए परिवर्तन वास्तव में बहुत नए हैं। निश्चित रूप से इन नई सुविधाओं पर नजर रखेगा, और उन्हें 12.1 रिलीज में देखने की उम्मीद है :) –
मैंने कुछ परीक्षण किया है और 2 प्रश्न हैं जो मुझे पहेली करते हैं: 1) न केवल श्रमिक, बल्कि मास्टर आने वाले कनेक्शन स्वीकार करेंगे - मैं केवल श्रमिकों को कैसे स्वीकार कर सकता हूं? 2) क्या यह सही है कि 'reactor.listenTCP' कॉल पर 'बैकलॉग' सेट करना कुल में सॉकेट पर लागू होगा - जो कर्नेल में कतार गहराई है, और इसलिए सभी श्रमिकों के लिए संयुक्त है? – oberstet