2017-08-28 8 views
12

start.py कोड नीचे जैसा है।थ्रेडिंग मॉड्यूल में एक ही प्रोग्राम अलग आउटपुट

import threading 
class myThread(threading.Thread): 
     def __init__(self, threadID, name): 
       threading.Thread.__init__(self) 
       self.threadID = threadID 
       self.name = name 

     def run(self): 
       currentThreadname = threading.currentThread() 
       print "running in ", currentThreadname 

thread = myThread(1,"mythrd") 
thread.start() 

इसे दो बार पाइथन के साथ शुरू करें।

python start.py 
running in <myThread(mythrd, started 140461133485824)> 
python start.py 
running in <myThread(mythrd, started 140122860668672)> 

run.py कोड नीचे जैसा है।

import threading 
class myThread(threading.Thread): 
     def __init__(self, threadID, name): 
       threading.Thread.__init__(self) 
       self.threadID = threadID 
       self.name = name 

     def run(self): 
       currentThreadname = threading.currentThread() 
       print "running in ", currentThreadname 

thread = myThread(1,"mythrd") 
thread.run() 

run.py start.py से केवल एक पंक्ति अलग है।
अब दो बार के लिए run.py शुरू करें।

python run.py 
running in <_MainThread(MainThread, started 139854546364160)> 
python run.py 
running in <_MainThread(MainThread, started 139854546364160)> 

startandrun.py कोड नीचे जैसा है।

class myThread(threading.Thread): 
    def __init__(self, threadID, name): 
     threading.Thread.__init__(self) 
     self.threadID = threadID 
     self.name = name 

    def run(self): 
     currentThreadname = threading.currentThread() 
     print "running in ", currentThreadname 

thread = myThread(1,"mythrd") 
thread.start() 
thread.run() 

अब दो बार के लिए startandrun.py शुरू करें।

python startandrun.py 
running in <myThread(mythrd, started 140317119899392)> 
running in <_MainThread(MainThread, started 140317144454912)> 
python startandrun.py 
running in running in <_MainThread(MainThread, started 139980210505472)> 
<myThread(mythrd, started 139980185949952)> 

JohanL के रूप में कहते हैं:
जब दो अलग-अलग धागे चल रहा है, सभी दांव बंद कर रहे हैं के रूप में जो पहले निष्पादित करेंगे।
आप मूल रूप से ऑपरेटिंग सिस्टम में शेड्यूलिंग छोड़ रहे हैं। startandrun.py निष्पादित करने के लिए पहली बार, thread.start()thread.run() से पहले मार डाला गया था, यह उत्पादन में परिणाम:

running in <myThread(mythrd, started 140317119899392)> 
running in <_MainThread(MainThread, started 140317144454912)> 

startandrun.py निष्पादित करने के लिए दूसरी बार, thread.start()thread.run() के बाद मार डाला गया था, क्यों उत्पादन में परिणाम नहीं :

running in <_MainThread(MainThread, started 140317144454912)> 
running in <myThread(mythrd, started 140317119899392)> 
बजाय

running in running in <_MainThread(MainThread, started 139980210505472)> 
<myThread(mythrd, started 139980185949952)> 
+1

जब दो अलग-अलग धागे चल रहा है, सभी दांव के रूप में बंद कर रहे हैं जो पहले निष्पादित करेगा। आप मूल रूप से ऑपरेटिंग सिस्टम में शेड्यूलिंग छोड़ रहे हैं। यही कारण है कि जब आप अपने धागे एक ही डेटा तक पहुंच रहे हों तो आपको विभिन्न सिंक्रनाइज़ेशन प्राइमेटिव (सेमफोर, मॉनीटर et.c.) की आवश्यकता होती है। – JohanL

+0

'thread.run' एक नया धागा शुरू नहीं करता है, इसलिए यह कोड शायद ऐसा नहीं कर रहा है जो आपको लगता है कि यह कर रहा है। धागा शुरू करने के लिए, आपको 'स्टार्ट' कॉल करना होगा। आपको सीधे 'रन' नहीं बुलाया जाना चाहिए, 'स्टार्ट' आपके लिए यह करेगा। कॉलिंग शुरू और रन सिर्फ उस समस्या को और भ्रमित करने में मदद करता है जिसे आप समझने की कोशिश कर रहे हैं। दस्तावेज़ देखें, जो इस बारे में काफी स्पष्ट हैं "एक बार थ्रेड ऑब्जेक्ट बनने के बाद, इसकी गतिविधि थ्रेड की प्रारंभ() विधि को कॉल करके प्रारंभ की जानी चाहिए। यह रन() विधि को नियंत्रण के एक अलग थ्रेड में आमंत्रित करता है।" – pvg

उत्तर

4

यह क्या हो रहा है, क्योंकि जिस तरह से आप मूल्यों प्रिंट कर रहे हैं:

print "running in ", currentThreadname 

एक अल्पविराम जोड़ने के समान है:

print 'running in ' # without new line at the end 
print currentThreadname 

और दो कार्यों के बाद से यहां एक ही समय में चल रहे हैं आदेश कैसे निष्पादित किया जाता है:

print 'running in ' # without new line FUNCTION #1 
print 'running in ' # without new line FUNCTION #2 
print currentThreadName # with new line at the end FUNCTION #1 
print currentThreadName # with new line at the end FUNCTION #2 

कॉमा के बिना एक प्रिंट स्टेटमेंट का उपयोग करने का प्रयास करें समझते हैं कि यह कैसे किया जाना चाहिए:

def run(self): 
    currentThreadname = threading.currentThread() 
    print "running in {}".format(currentThreadname) 

यह सामान्य रूप से व्यवहार करेंगे लेकिन जब से दो कार्य एक ही समय में प्रिंट कर रहे हैं, तो आप निम्न उत्पादन प्राप्त कर सकते हैं: साबित होता है कि यह काम करेगा

running in <myThread(mythrd, started 10716)>running in <_MainThread(MainThread, started 12132)> 

तो आप time.sleep() का उपयोग कर दो कॉल के बीच में देरी का उपयोग कर सकते हैं:

import threading 
import time 

class myThread(threading.Thread): 
    def __init__(self, threadID, name): 
     threading.Thread.__init__(self) 
     self.threadID = threadID 
     self.name = name 

    def run(self): 
     currentThreadname = threading.currentThread() 
     print "running in {}".format(currentThreadname) 

thread = myThread(1,"mythrd") 
thread.start() 
time.sleep(0.1) 
thread.run() 

अब आप देख सकते हैं कि आप अपने वांछित उत्पादन मिलता है क्योंकि प्रत्येक कार्य एक टिम प्रिंट कर रहा है कॉल के बीच में एक 0.1 सेकंड देरी के साथ ई:

running in <myThread(mythrd, started 5600)> 
running in <_MainThread(MainThread, started 7716)> 

संपादित करें:

आपका मुद्दा ठीक है तुम क्यों इस्तेमाल करना चाहिए multithreading के बजाय एक ही धागे में दो बार चल रहा है। जब आप मल्टीथ्रेडिंग का उपयोग करते हैं तो आप thread.join() का उपयोग कर सकते हैं जो थ्रेड को समाप्त करने के लिए प्रतीक्षा करेगा और फिर कोड जारी रखेगा, या आप threading.lock() का उपयोग कर सकते हैं ताकि आप अपना कोड जारी रख सकें लेकिन एक समय में एक थ्रेड द्वारा उपयोग किए जाने वाले फ़ंक्शन को लॉक कर सकें। यहाँ कुछ उदाहरण हैं:

thread.join():

thread = myThread(1, "mythrd") 
thread2 = myThread(2, "thrd2") 
thread.start() 
thread.join() # code will stop here and wait for thread to finish then continue 
thread2.run() 

threading.lock():

.... 
    def run(self): 
     with lock: # if one thread uses this lock the other threads have to wait 
      currentThreadname = threading.currentThread() 
      print "running in ", currentThreadname 

thread = myThread(1, "mythrd") 
thread2 = myThread(2, "thrd2") 
lock = threading.Lock() 
thread.start() 
thread2.run() 
# code keeps running even if there are threads waiting for the lock 
+0

मैं शुरुआत से सहमत नहीं हूं (और शायद यह ओपी की समस्या थी), हालांकि मुझे नहीं लगता कि यह संभव है आपके द्वारा वर्णित एक पंक्ति मामले पर सबकुछ (इसका मतलब यह होगा कि लाइन-फीड अलग-अलग stdout स्ट्रीम में लिखी जाती है) – MacHala

+0

@MacHala यदि दो धागे प्रिंटिंग हो तो यह संभव नहीं है, लेकिन यहां एक धागा दो कार्यों को चला रहा है और दोनों फ़ंक्शन प्रिंट कर रहे हैं –

0

कौन-सा संस्करण अजगर wer क्या आप उपयोग कर रहे हैं? पायथन 2 में, "प्रिंट" थ्रेड सुरक्षित नहीं है। कृपया http://tech.queryhome.com/54593/is-print-thread-safe-in-python-2-6-2-7 देखें।

यदि धागे "प्रिंट" के दौरान स्विच करते हैं, तो आउटपुट मिश्रित होते हैं, जैसा आपने देखा था।

+1

यह स्पष्ट रूप से पायथन 2 वाक्यविन्यास दिया गया है। और यह 'थ्रेडसेफ' का मतलब नहीं है। – pvg

+0

@pvg, तो "थ्रेड सुरक्षित" का क्या अर्थ है? – VHao

+1

वीएचओ सही है; सन्दर्भ को अधिक तर्क लिखने के दौरान स्विच किया जा सकता है, जिसके परिणामस्वरूप अप्रत्याशित आउटपुट होता है, जिसे इम्हो को अच्छी तरह से वर्णित किया जा सकता है क्योंकि थ्रेडसेफ – MacHala

2

तो, आप चाहते हैं कि आप अपने धागे को सिंक्रनाइज़ करें। इसे आसानी से का उपयोग करके() थ्रेडिंग लाइब्रेरी में फ़ंक्शन का उपयोग करके आसानी से किया जा सकता है।

आप इस

class myThread(threading.Thread): 
    def __init__(self, threadID, name): 
     threading.Thread.__init__(self) 
     self.threadID = threadID 
     self.name = name 

    def run(self): 
     currentThreadname = threading.currentThread() 
     print "running in ", currentThreadname 

thread = myThread(1,"mythrd") 
t1 = thread.start() 
t1.join() 
t2 = thread.run() 
t2.join() 

तुम भी बेहतर कारणों के लिए सेमाफोर और लॉक का उपयोग कर सकते की तरह कुछ कर सकते हैं। अधिक जानकारी के लिए दस्तावेज़ देखें।

2

शायद आपको समझ में नहीं आता कि थ्रेड कैसे काम कर रहे हैं। this ध्यान से पढ़ें।

मैं आपको futures लाइब्रेरी से ThreadPoolExecutor का उपयोग करने का सुझाव देता हूं।

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