2012-11-02 19 views
13

पढ़ना http://bugs.python.org/msg160297, मैं जो यह दर्शाता है स्टीफन व्हाइट द्वारा लिखित एक सरल स्क्रिप्ट देख सकते हैं कि अजगर सूत्रण इस अपवादसमझ अजगर सूत्रण बग

Exception AttributeError: AttributeError("'_DummyThread' object has no attribute '_Thread__block'",) in <module 'threading' 

स्टीफन व्हाइट के स्रोत कोड को देखते हुए (http के साथ कीड़े अप: //bugs.python .org/file25511/bad-thread.py),

import os 
import thread 
import threading 
import time 

def t(): 
    threading.currentThread() # Populate threading._active with a DummyThread 
    time.sleep(3) 

thread.start_new_thread(t,()) 

time.sleep(1) 

pid = os.fork() 
if pid == 0: 
    os._exit(0) 

os.waitpid(pid, 0) 

कैसे हम इसे फिर से लिखना होगा ताकि इस त्रुटि हल हो गई है?

+0

ऐसा लगता है कि आप इसे 'time.sleep (3) 'के रूप में पुनः लिख सकते हैं। मुझे लगता है कि आपको यह निर्दिष्ट करना चाहिए कि पुनर्लेखित कार्यक्रम वास्तव में क्या करना चाहिए। –

+3

@JanneKarila कार्यक्रम केवल एक पायथन बग प्रदर्शित करता है, जो आप देखेंगे कि क्या आप इसे पायथन 2.7 में चलाते हैं। अनुरोध एक पाइथन रिलीज को अपग्रेड किए बिना बग के आसपास काम करना है जो इसे ठीक करता है। – user4815162342

उत्तर

33

The bug डमी धागा वस्तुओं जब एक एक विदेशी धागे पर threading.currentThread() कॉल threading API द्वारा निर्मित के बीच एक बुरी संपर्क, और threading._after_fork समारोह, os.fork() के लिए एक कॉल के बाद संसाधनों को साफ करने के लिए बुलाया के कारण होती है।

__stop की नो-सेशन कार्यान्वयन के साथ पायथन के स्रोत, बंदर पैच threading._DummyThread को संशोधित किए बिना बग हल करने के लिए:

import threading 
threading._DummyThread._Thread__stop = lambda x: 42 

बग के कारण सबसे अच्छा Richard Oudkerk और cooyeah द्वारा टिप्पणी में संकुचित है।

  1. threading मॉड्यूल threading.currentThread() नहीं threading API कॉल के द्वारा बनाई गई एक धागे से कहा जा सकता है: क्या होता है निम्नलिखित है। इसके बाद यह एक "डमी थ्रेड" उदाहरण देता है जो Thread एपीआई के बहुत सीमित सबसेट का समर्थन करता है, लेकिन वर्तमान धागे की पहचान के लिए अभी भी उपयोगी है।

  2. threading._DummyThreadThread के उप-वर्ग के रूप में लागू किया गया है। Thread उदाहरणों में आम तौर पर एक आंतरिक कॉल करने योग्य (self.__block) होता है जो आवृत्ति के लिए आवंटित ओएस-स्तरीय लॉक के संदर्भ में रहता है। चूंकि सार्वजनिक Thread विधियों का उपयोग self.__block का उपयोग कर समाप्त हो सकता है, इसलिए _DummyThread, _DummyThread के निर्माता द्वारा जानबूझकर ओवरराइड किया गया है self.__block हटाकर जानबूझकर ओएस-स्तरीय लॉक जारी करता है।

  3. threading._after_fork कैप्सूलीकरण टूट जाता है और पर सभी पंजीकृत सूत्र, डमी हैं, जहां __stop लागू किया जा करने के लिए होती कभी नहीं किया गया था सहित निजी Thread.__stop प्रणाली को बुलाती है। (वे पाइथन द्वारा शुरू नहीं किए गए थे, इसलिए उनका रोकथाम पाइथन द्वारा प्रबंधित नहीं किया जाता है।) जैसे डमी धागे __stop के बारे में नहीं जानते हैं, वे इसे Thread से प्राप्त करते हैं, और यह कार्यान्वयन खुशी से निजी __block विशेषता का उपयोग नहीं करता है _DummyThread उदाहरणों में मौजूद है। अंततः यह पहुंच त्रुटि का कारण बनती है।

बग modifying Thread.__stop not to break से 2.7 शाखा में ठीक किया गया जब __block नष्ट कर दिया जाता है। 3.x शाखा, जहां __stop को _stop के रूप में लिखा गया है और इसलिए संरक्षित है, इसे overriding _DummyThread's _stop to do nothing द्वारा ठीक करता है।

+0

आह ... मुझे अब मिल गया ... धन्यवाद! –

+0

शानदार स्पष्टीकरण! –

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