2011-08-03 10 views
39

क्या लिनक्स पर पाइथन में सिस्टम-व्यापी म्यूटेक्स रखने का कोई आसान तरीका है? "सिस्टम-वाइड" द्वारा, मेरा मतलब है कि म्यूटेक्स का उपयोग पायथन प्रक्रियाओं के समूह द्वारा किया जाएगा; यह पारंपरिक म्यूटेक्स के विपरीत है, जिसका उपयोग उसी प्रक्रिया में थ्रेड के समूह द्वारा किया जाता है।लिनक्स पर पाइथन में सिस्टम-व्यापी म्यूटेक्स

संपादित करें: मुझे यकीन नहीं है कि पायथन का multiprocessing पैकेज मुझे चाहिए। उदाहरण के लिए, मैं दो अलग अलग दुभाषिए में निम्नलिखित निष्पादित कर सकते हैं: जब मैं दो अलग-अलग दुभाषिए में एक साथ इन आदेश पर अमल

from multiprocessing import Lock 
L = Lock() 
L.acquire() 

, मैं उनमें से एक-मस्ती करना चाहते। इसके बजाए, न तो लटका; ऐसा प्रतीत होता है कि वे एक ही म्यूटेक्स प्राप्त नहीं कर रहे हैं।

+0

http://stackoverflow.com/questions/5756813/simple-but-fast-ipc-method-for-a-python-and-c-application – Anycorn

+0

आप शामिल हैं एक अच्छा समाधान मिला? – redice

उत्तर

22

"पारंपरिक" यूनिक्स उत्तर फ़ाइल ताले का उपयोग करना है। आप फ़ाइल के अनुभागों को लॉक करने के लिए lockf(3) का उपयोग कर सकते हैं ताकि अन्य प्रक्रियाएं इसे संपादित नहीं कर सकें; प्रक्रियाओं के बीच एक म्यूटेक्स के रूप में इसका उपयोग करना बहुत आम दुर्व्यवहार है। पायथन बराबर fcntl.lockf है।

परंपरागत रूप से आप लॉकिंग प्रक्रिया में लॉकिंग प्रक्रिया के पीआईडी ​​को लॉक फ़ाइल में लिखते हैं, ताकि लॉक रखने के दौरान मरने वाली प्रक्रियाओं के कारण डेडलॉक्स पहचाने जाने योग्य और फिक्स करने योग्य हों।

यह आपको प्राप्त करता है जो आप चाहते हैं, क्योंकि आपका लॉक वैश्विक नामस्थान (फाइल सिस्टम) में है और सभी प्रक्रियाओं के लिए सुलभ है। इस दृष्टिकोण में यह भी है कि गैर-पायथन कार्यक्रम आपके लॉकिंग में भाग ले सकते हैं। नकारात्मकता यह है कि आपको इस लॉक फ़ाइल को जीने के लिए एक जगह चाहिए; भी, कुछ फाइल सिस्टम वास्तव में सही ढंग से लॉक नहीं होते हैं, इसलिए एक जोखिम है कि यह चुपचाप बहिष्कार प्राप्त करने में विफल हो जाएगा। तुम कुछ जीतते हो तो कुछ हारते हो।

+1

लॉक फ़ाइल के लिए तार्किक स्थान '/ var/lock' है - हालांकि यदि लॉकिंग ऑपरेशंस की एक बड़ी संख्या होने जा रही है, तो मैं' tmpfs 'में सुझाव देता हूं क्योंकि सभी सिस्टमों में 't varfs' में'/var/lock' नहीं है रैमडिस्क। – Kimvais

+0

सभी सिस्टमों में tmpfs ramdisk में/tmp नहीं है; ओएस एक्स का मेरा इंस्टॉलेशन प्रतीत नहीं होता है। हालांकि, सभी अच्छे अंक अच्छे हैं। – zmccord

+0

वह _linux_ के बारे में पूछ रहा था और प्रमुख आधुनिक लिनक्स डिस्ट्रोज़ में अधिकांश (यदि नहीं सभी)/tmpfs में/tmpfs हैं - डिफ़ॉल्ट IIRC द्वारा कोई भी/var/lock नहीं है। – Kimvais

10

POSIX मानक अंतर-प्रक्रिया सेमफोर निर्दिष्ट करता है जिसका उपयोग इस उद्देश्य के लिए किया जा सकता है। http://linux.die.net/man/7/sem_overview

पाइथन में multiprocessing मॉड्यूल इस एपीआई और अन्य पर बनाया गया है। विशेष रूप से, multiprocessing.Lock एक क्रॉस-प्रोसेस "म्यूटेक्स" प्रदान करता है। http://docs.python.org/library/multiprocessing.html#synchronization-between-processes

संपादित संपादित प्रश्न पर प्रतिक्रिया के लिए:

अवधारणा प्रत्येक प्रक्रिया एक Lock() निर्माण कर रही है का प्रमाण हैं। तो आपके पास दो अलग ताले हैं। यही कारण है कि न तो प्रक्रिया इंतजार कर रही है। आपको प्रक्रियाओं के बीच एक ही लॉक साझा करने की आवश्यकता होगी। multiprocessing दस्तावेज में जो अनुभाग मैंने लिंक किया है, वह बताता है कि यह कैसे करें।

+0

धन्यवाद, लेकिन "मल्टीप्रोसेसिंग" मुझे जो चाहिए वह प्रतीत नहीं होता है; संपादित प्रश्न देखें। – emchristiansen

+0

मेरा जवाब संपादित करना। – wberry

+15

आपके द्वारा लिंक किया गया अनुभाग यह दिखाने के लिए प्रतीत होता है कि एक मास्टर प्रक्रिया 10 प्रक्रियाओं को कैसे उत्पन्न कर सकती है, जिससे प्रत्येक व्यक्ति को लॉक ऑब्जेक्ट को पास किया जा सकता है। मेरा उपयोग मामला अलग है, क्योंकि उपप्रोसेस उत्पन्न करने वाली कोई मास्टर प्रक्रिया नहीं है। मेरे मामले में, प्रत्येक प्रक्रिया पूरी तरह से स्वतंत्र रूप से आक्रमण की जाती है, लेकिन उन्हें अभी भी समन्वय करना होगा। – emchristiansen

0

एक सिस्टम-व्यापी म्यूटेक्स के लिए जो पूरी तरह से अलग प्रक्रियाओं के सिंक्रनाइज़ेशन को सक्षम बनाता है (यानी, लिनक्स प्रक्रियाओं को शामिल करने के लिए जो एक ही प्रक्रिया पेड़ से संबंधित नहीं हैं), बस fcntl.flock का उपयोग करें। मुझे लगता है कि लिनक्स '/ रन/शम फ़ोल्डर के तहत एक मेमोरी फ़ाइल का उपयोग करके यह तेजी से प्रदर्शन कर सकता है।

और देखें here

0

प्रयास करें ilock पुस्तकालय:

from ilock import ILock 

with ILock('Unique lock name'): 
    # The code should be run as a system-wide single instance 
    ... 
संबंधित मुद्दे