मेरे पास संभवतः लंबे समय तक चलने वाला प्रोग्राम है जिसमें वर्तमान में 4 प्रक्रियाएं हैं, लेकिन अधिक होने के लिए कॉन्फ़िगर किया जा सकता है। मैंने पाइथन के logging
का उपयोग करके logging from multiple processes पर शोध किया है और here पर चर्चा की गई सॉकेटहैंडलर दृष्टिकोण का उपयोग कर रहा हूं। मुझे कभी भी एक लॉगर (कोई सॉकेट नहीं) होने में कोई समस्या नहीं थी, लेकिन जो मैंने पढ़ा उससे मुझे बताया गया कि यह अंततः और अप्रत्याशित रूप से विफल हो जाएगा। जहां तक मैं इसे अज्ञात समझता हूं, तब भी होगा जब आप एक ही समय में एक ही फाइल को लिखने का प्रयास करेंगे। मेरे कोड अनिवार्य रूप से निम्नलिखित है:एकाधिक प्रक्रियाओं से पाइथन लॉगिंग
import logging
log = logging.getLogger(__name__)
def monitor(...):
# Spawn child processes with os.fork()
# os.wait() and act accordingly
def main():
log_server_pid = os.fork()
if log_server_pid == 0:
# Create a LogRecordSocketServer (daemon)
...
sys.exit(0)
# Add SocketHandler to root logger
...
monitor(<configuration stuff>)
if __name__ == "__main__":
main()
तो मेरी प्रश्न हैं: मैं हर os.fork()
के बाद एक नया log
वस्तु बनाने की जरूरत है? मौजूदा वैश्विक log
ऑब्जेक्ट का क्या होता है?
चीजों को करने के तरीके के साथ, क्या मैं भी उस समस्या के आसपास हो रहा हूं जिसे मैं टालने की कोशिश कर रहा हूं (एकाधिक खुली फ़ाइलें/सॉकेट)? क्या यह असफल हो जाएगा और यह क्यों विफल रहेगा (मैं यह बताना चाहता हूं कि भविष्य में समान कार्यान्वयन विफल हो जाएंगे)?
इसके अलावा, कई प्रक्रियाओं से एक फ़ाइल में लॉगिंग करने की "सामान्य" (एक log=
अभिव्यक्ति) विधि किस तरह से विफल हो जाती है? क्या यह IOError/OSError उठाता है? या यह फ़ाइल को पूरी तरह से डेटा नहीं लिखता है?
अगर कोई मेरी मदद करने के लिए उत्तर या लिंक प्रदान कर सकता है, तो यह बहुत अच्छा होगा। धन्यवाद।
FYI करें: मैं पर मैक ओएस एक्स शेर का परीक्षण कर रहा हूँ और कोड शायद एक Windows मशीन पर एक CentOS 6 वी एम पर चल रहा है खत्म हो जाएगा (यदि यह मायने रखती है)। जो भी समाधान मैं उपयोग करता हूं उसे विंडोज पर काम करने की आवश्यकता नहीं है, लेकिन यूनिक्स आधारित सिस्टम पर काम करना चाहिए।
अद्यतन: यह प्रश्न विशिष्ट व्यवहार को लॉगिंग से दूर जाना शुरू कर दिया है और फोर्क के दौरान लिनक्स फ़ाइल डिस्क्रिप्टर के साथ क्या करता है इसके दायरे में अधिक है। मैंने अपनी कॉलेज पाठ्यपुस्तकों में से एक को खींच लिया और ऐसा लगता है कि यदि आप दो प्रक्रियाओं (एक कांटा से पहले नहीं) से एपेंड मोड में एक फ़ाइल खोलते हैं, तो वे दोनों फाइल ठीक से फ़ाइल में लिखने में सक्षम होंगे जब तक कि आपका लेखन अधिक न हो वास्तविक कर्नेल बफर (हालांकि लाइन बफरिंग का उपयोग करने की आवश्यकता हो सकती है, फिर भी उस पर निश्चित नहीं है)। यह 2 फ़ाइल टेबल प्रविष्टियों और एक वी-नोड तालिका प्रविष्टि बनाता है। फ़ाइल खोलना तब फोर्किंग काम नहीं करना चाहिए, लेकिन ऐसा लगता है कि जब तक आप पहले से कर्नेल बफर से अधिक नहीं होते हैं (मैंने इसे पिछले प्रोग्राम में किया है)।
तो मुझे लगता है कि यदि आप मंच स्वतंत्र स्वतंत्र बहु-प्रसंस्करण लॉगिंग चाहते हैं तो आप सॉकेट का उपयोग करें और प्रत्येक कांटा को सुरक्षित रखने के बाद एक नया सॉकेटहैंडलर बनाएं क्योंकि विनय ने नीचे सुझाव दिया है (जो हर जगह काम करना चाहिए)। मेरे लिए, चूंकि मेरे पास ओएस का सॉफ़्टवेयर चल रहा है, इस पर मेरा मजबूत नियंत्रण है, मुझे लगता है कि मैं एक वैश्विक log
ऑब्जेक्ट के साथ फाइलहैंडलर के साथ जा रहा हूं (डिफ़ॉल्ट रूप से एपेंड मोड में खुलता है और अधिकांश ओएस पर बफर किया जाता है)। open
के लिए प्रलेखन कहता है "एक नकारात्मक बफरिंग का मतलब सिस्टम डिफ़ॉल्ट का उपयोग करना है, जो आम तौर पर टीटीई उपकरणों के लिए लाइन buffered है और अन्य फ़ाइलों के लिए पूरी तरह से buffered है। अगर छोड़ा गया है, तो सिस्टम डिफ़ॉल्ट का उपयोग किया जाता है।" या लाइन बफरिंग सुनिश्चित करने के लिए मैं अपनी खुद की लॉगिंग स्ट्रीम बना सकता हूं। और बस स्पष्ट होना, मैं के साथ ठीक हूँ:
# Process A
a_file.write("A\n")
a_file.write("A\n")
# Process B
a_file.write("B\n")
उत्पादन ...
A\n
B\n
A\n
जब तक कि यह उत्पादन नहीं करता है के रूप में ...
AB\n
\n
A\n
विनय (या किसी और), कैसे गलत हूँ? मुझे बताएं। आप जो भी स्पष्टता/सुनिश्चित कर सकते हैं उसके लिए धन्यवाद।
धागे और ताले इस तरह की चीजों के लिए उपयोगी हैं ... –
मुझे अलग प्रक्रियाओं की आवश्यकता है क्योंकि बच्चे बाहरी उपकरणों के साथ संचार कर रहे हैं जो जितना संभव हो सके "त्वरित" होना चाहिए। – daveydave400
मैंने अपना जवाब अपडेट किया। –