2012-05-09 26 views
33

मैं थ्रेडिंग और समरूपता की मूल बातें समझने की कोशिश कर रहा हूं। मुझे एक साधारण मामला चाहिए जहां दो धागे बार-बार एक साझा संसाधन तक पहुंचने का प्रयास करते हैं।पायथन थ्रेडिंग। मैं धागा कैसे लॉक करूं?

कोड:

import threading 

class Thread(threading.Thread): 
    def __init__(self, t, *args): 
     threading.Thread.__init__(self, target=t, args=args) 
     self.start() 
count = 0 
lock = threading.Lock() 

def incre(): 
    global count 
    lock.acquire() 
    try: 
     count += 1  
    finally: 
     lock.release() 

def bye(): 
    while True: 
     incre() 

def hello_there(): 
    while True: 
     incre() 

def main():  
    hello = Thread(hello_there) 
    goodbye = Thread(bye) 

    while True: 
     print count 

if __name__ == '__main__': 
    main() 

तो, मैं दो धागे है, दोनों काउंटर बढ़ाने के लिए कोशिश कर रहा। मैंने सोचा कि अगर थ्रेड 'ए' को incre() कहा जाता है, तो lock स्थापित किया जाएगा, 'बी' को 'ए' जारी होने तक पहुंचने से रोक दिया जाएगा।

रनिंग यह स्पष्ट करता है कि यह मामला नहीं है। आपको सभी यादृच्छिक डेटा रेस-आईएसएच वृद्धि मिलती है।

लॉक ऑब्जेक्ट का उपयोग कैसे किया जाता है?

संपादित करें, इसके अतिरिक्त, मैंने ताले कार्यों के अंदर ताले लगाने की कोशिश की है, लेकिन अभी भी कोई भाग्य नहीं है।

+0

आपका कोड नहीं चलता है। –

+0

@Ignacio Vazquez-Abrams - अब चाहिए। मैंने 'if __name__' बिट छोड़ा। क्या आप इसका जिक्र कर रहे थे? – Zack

+1

यह मेरे लिए भी नहीं चलता है। मैं उम्मीद करता हूं कि आपकी थ्रेड सृजन इस तरह दिखने की उम्मीद करेगी: 'हैलो = थ्रेडिंग। थ्रेड (लक्ष्य = हैलो_टेयर)' और फिर धागे को शुरू करने के लिए 'हैलो.स्टार्ट() '। –

उत्तर

40

आप देख सकते हैं कि यदि आप प्रक्रिया को धीमा करते हैं और उन्हें थोड़ा और अवरुद्ध करते हैं, तो आप देख सकते हैं कि आपके ताले बहुत अधिक काम कर रहे हैं। आपके पास सही विचार था, जहां आप लॉक के साथ कोड के महत्वपूर्ण टुकड़ों को घेरते हैं। यहां आपको यह दिखाने के लिए एक छोटा समायोजन है कि प्रत्येक लॉक को रिहा करने के लिए दूसरे पर कैसे इंतजार करता है।

import threading 
import time 
import inspect 

class Thread(threading.Thread): 
    def __init__(self, t, *args): 
     threading.Thread.__init__(self, target=t, args=args) 
     self.start() 

count = 0 
lock = threading.Lock() 

def incre(): 
    global count 
    caller = inspect.getouterframes(inspect.currentframe())[1][3] 
    print "Inside %s()" % caller 
    print "Acquiring lock" 
    with lock: 
     print "Lock Acquired" 
     count += 1 
     time.sleep(2) 

def bye(): 
    while count < 5: 
     incre() 

def hello_there(): 
    while count < 5: 
     incre() 

def main():  
    hello = Thread(hello_there) 
    goodbye = Thread(bye) 


if __name__ == '__main__': 
    main() 

नमूना उत्पादन:

... 
Inside hello_there() 
Acquiring lock 
Lock Acquired 
Inside bye() 
Acquiring lock 
Lock Acquired 
... 
+0

ओह, साफ! मुझे लगता है कि मैं 'प्रिंट गिनती' द्वारा 'मुख्य()' में अनियमित पुनरावृत्ति दिखा रहा हूं। लेकिन मुझे लगता है कि यह ऐसा लगता है कि मेरे पास तीन लूप एक साथ चल रहे थे। धन्यवाद! निरीक्षण मॉड्यूल के बारे में भी टीआईएल। बहुत ही शांत। – Zack

+0

@Zack: हां मुझे लगता है कि यह मुख्य प्रिंट आपको भ्रमित कर रहा था। इसकी कोई सीमा नहीं थी, इसलिए धागे की तुलना में तेज़ प्रिंटिंग भी बदल रही थी। – jdi

+0

@jdi मैं लॉकिंग को समझने की कोशिश कर रहा हूं, इसलिए मैंने गिनती + = 1 के ठीक बाद आपके वृद्धि फ़ंक्शन में एक प्रिंट (गिनती) जोड़ा, लेकिन जब मैं कोड चलाता हूं तो यह 6 हो जाता है? – ErinGoBragh

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