दिलचस्प पोस्ट
क्या पोस्टग्रेर्स नेस्टेड या स्वायत्त लेनदेन का समर्थन किया है? आर doParallel 'foreach' में कार्य नहीं मिला – {: कार्य 1 में त्रुटि विफल – "फ़ंक्शन" रेस्टर "" नहीं मिल सका "" जीआईटी सबड्यूल और सबट्री के बीच मतभेद 'विंडो' पर 'btoa' निष्पादित करने में असफल: एन्कोड किए जाने वाली स्ट्रिंग में लैटिन 1 श्रेणी के बाहर के अक्षर शामिल हैं अजाक्स का उपयोग करके आंशिक दृश्य प्रस्तुत करना MVVM: ट्यूटोरियल शुरू से खत्म करने के लिए? jqGrid और गतिशील कॉलम बाइंडिंग Android WebView शैली पृष्ठभूमि-रंग: पारदर्शी Android 2.2 पर ध्यान नहीं दिया क्यों जावा अग्रज तत्व मूल्य नहीं बदलता है? कर्सर को जावास्क्रिप्ट प्रतिलिपि में इनपुट फील्ड के अंत तक कूदने से रोकें एक्लिप्से, एडीटी 22.6 से एंड्रॉइड वर्चुअल डिवाइसेस (एवीडी) को बना या संपादित नहीं किया जा सकता java.lang.ClassNotFoundException: org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter जब सरल Struts2 अनुप्रयोग शुरू करते हैं TypeScript "त्रुटि TS2533 को दबाने के लिए कैसे: ऑब्जेक्ट संभवतः 'रिक्त' या 'अपरिभाषित'" है? लिनक्स में तकिया (पायथन मॉड्यूल) की स्थापना के दौरान विफल जावास्क्रिप्ट का उपयोग कर सेलेनियम वेबड्राइवर में एक तत्व को कैसे क्लिक करें

पायथन में थ्रेडिंग का उपयोग कैसे करें?

मैं पायथन में थ्रेडिंग को समझने की कोशिश कर रहा हूं। मैंने दस्तावेज़ीकरण और उदाहरणों को देखा है, लेकिन बहुत स्पष्ट रूप से, बहुत से उदाहरणों को अत्यधिक परिष्कृत किया गया है और उन्हें समझने में मुझे परेशानी है।

बहु-थ्रेडिंग के लिए विभाजित कार्यों को आप स्पष्ट रूप से कैसे दिखाते हैं?

Solutions Collecting From Web of "पायथन में थ्रेडिंग का उपयोग कैसे करें?"

चूंकि इस प्रश्न को 2010 में पूछा गया था, मैथ्यू और पूल के साथ अजगर के साथ सरल मल्टीथ्रेडिंग करने में असली सरलीकरण किया गया है।

नीचे दिए गए कोड एक आलेख / ब्लॉग पोस्ट से आता है जिसे आपको निश्चित रूप से जांचना चाहिए (कोई भी संबद्धता नहीं) – एक पंक्ति में समानता: दिन के लिए थ्रेडिंग कार्य के लिए एक बेहतर मॉडल । मैं नीचे संक्षेप में बताऊँगा – यह सिर्फ कोड की कुछ पंक्तियां समाप्त होती है:

from multiprocessing.dummy import Pool as ThreadPool pool = ThreadPool(4) results = pool.map(my_function, my_array) 

का मल्टीथ्रेड वाला संस्करण कौन सा है:

 results = [] for item in my_array: results.append(my_function(item)) 

विवरण

मानचित्र एक शांत सा समारोह है, और अपने पायथन कोड में समानांतरता को आसानी से इंजेक्शन करने की कुंजी है। उन अपरिचित के लिए, नक्शा लिस्प जैसी कार्यात्मक भाषाओं से कुछ उठाया जाता है यह एक ऐसा फ़ंक्शन होता है, जो एक अनुक्रम पर दूसरे फ़ंक्शन को मैप करता है।

मैप हमारे लिए अनुक्रम पर पुनरावृत्ति को संभालता है, फ़ंक्शन पर लागू होता है, और अंत में एक आसान सूची में सभी परिणाम स्टोर करता है।

यहां छवि विवरण दर्ज करें


कार्यान्वयन

मैप फ़ंक्शन के समानांतर संस्करण दो पुस्तकालयों द्वारा प्रदान किए जाते हैं: मल्टिप्रोकसेसिंग, और इसके छोटे ज्ञात, लेकिन समान रूप से शानदार कदम बच्चे: multiprocessing.dummy।

 import urllib2 from multiprocessing.dummy import Pool as ThreadPool urls = [ 'http://www.python.org', 'http://www.python.org/about/', 'http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html', 'http://www.python.org/doc/', 'http://www.python.org/download/', 'http://www.python.org/getit/', 'http://www.python.org/community/', 'https://wiki.python.org/moin/', ] # make the Pool of workers pool = ThreadPool(4) # open the urls in their own threads # and return the results results = pool.map(urllib2.urlopen, urls) # close the pool and wait for the work to finish pool.close() pool.join() 

और समय के परिणाम:

 Single thread: 14.4 seconds 4 Pool: 3.1 seconds 8 Pool: 1.4 seconds 13 Pool: 1.3 seconds 

एकाधिक तर्कों को पारित करना (इस तरह केवल Python 3.3 और बाद में काम करता है): ( स्रोत ):

कई सरणियों को पारित करने के लिए:

 results = pool.starmap(function, zip(list_a, list_b)) 

या निरंतर और एक सरणी को पारित करने के लिए:

 results = pool.starmap(function, zip(itertools.repeat(constant), list_a)) 

यदि आप पायथन के पूर्व संस्करण का उपयोग कर रहे हैं, तो आप इस समाधान के माध्यम से कई तर्कों को पारित कर सकते हैं।

(उपयोगी टिप्पणी के लिए उपयोगकर्ता 136036 के लिए धन्यवाद)

यहां एक सरल उदाहरण है: आपको कुछ वैकल्पिक यूआरएल देखने की जरूरत है और जवाब देने के लिए पहले एक की सामग्री वापस करनी होगी।

 import Queue import threading import urllib2 # called by each thread def get_url(q, url): q.put(urllib2.urlopen(url).read()) theurls = ["http://google.com", "http://yahoo.com"] q = Queue.Queue() for u in theurls: t = threading.Thread(target=get_url, args = (q,u)) t.daemon = True t.start() s = q.get() print s 

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

पायथन में धागे का उचित उपयोग हमेशा I / O कार्यों से जुड़ा होता है (चूंकि सीपीआईथॉन सीपीयू-बाध्य कार्यों को चलाने के लिए कई कोर का उपयोग नहीं करता है, थ्रेडिंग का एकमात्र कारण प्रक्रिया को अवरुद्ध नहीं कर रहा है, जबकि कुछ आई / ओ के लिए प्रतीक्षा है )। कतारें लगभग हमेशा काम करने के लिए धागे को खेती करने के लिए और / या काम के परिणामों को एकत्रित करने का सबसे अच्छा तरीका है, और वे आंतरिक रूप से थ्रेसेफ हैं ताकि वे आपको ताले, परिस्थितियों, घटनाओं, सिकफाओ, और अन्य अंतर- धागा समन्वय / संचार अवधारणाओं

नोट : पायथन में वास्तविक समानांतर के लिए, आपको एकाधिक प्रक्रियाओं का उपयोग करने के लिए मल्टी प्रोकक्शन मॉड्यूल का उपयोग करना चाहिए जो समानांतर में निष्पादित होते हैं (वैश्विक इंटरप्रेटर लॉक के कारण, पायथन थ्रेड्स इंटरलीविंग प्रदान करते हैं लेकिन वास्तव में क्रमिक रूप से निष्पादित होता है, समानांतर में नहीं, और केवल तब उपयोगी होता है जब interleaving I / O संचालन)।

हालांकि, यदि आप केवल interleaving (या I / O संचालन कर रहे हैं जो कि वैश्विक दुभाषिया लॉक के बावजूद समानांतर किया जा सकता है) की तलाश कर रहे हैं, तो थ्रेडिंग मॉड्यूल प्रारंभ करने के लिए जगह है। वास्तव में एक सरल उदाहरण के रूप में, समांतर में उपन्यासों को सम्मिलित करके एक बड़ी रेंज का समाधान करने की समस्या पर विचार करें:

 import threading class SummingThread(threading.Thread): def __init__(self,low,high): super(SummingThread, self).__init__() self.low=low self.high=high self.total=0 def run(self): for i in range(self.low,self.high): self.total+=i thread1 = SummingThread(0,500000) thread2 = SummingThread(500000,1000000) thread1.start() # This actually causes the thread to run thread2.start() thread1.join() # This waits until the thread has completed thread2.join() # At this point, both threads have completed result = thread1.total + thread2.total print result 

ध्यान दें कि ऊपर एक बहुत ही बेवकूफ उदाहरण है, क्योंकि यह बिल्कुल नहीं I / O है और सीपीआईथॉन में ग्लोबल इंटरप्रीटर लॉक के कारण इंटरलीव्ड (संदर्भ स्विचिंग के ओवरहेड के साथ) धारा में निष्पादित किया जाएगा।

सिर्फ एक नोट, सूत्र को थ्रेड करने के लिए कतार की आवश्यकता नहीं है।

यह सबसे आसान उदाहरण है, मैं कल्पना कर सकता हूं कि 10 प्रक्रियाएं एक साथ चलती हैं।

 import threading from random import randint from time import sleep def print_number(number): # Sleeps a random 1 to 10 seconds rand_int_var = randint(1, 10) sleep(rand_int_var) print "Thread " + str(number) + " slept for " + str(rand_int_var) + " seconds" thread_list = [] for i in range(1, 10): # Instantiates the thread # (i) does not make a sequence, so (i,) t = threading.Thread(target=print_number, args=(i,)) # Sticks the thread in a list so that it remains accessible thread_list.append(t) # Starts threads for thread in thread_list: thread.start() # This blocks the calling thread until the thread whose join() method is called is terminated. # From http://docs.python.org/2/library/threading.html#thread-objects for thread in thread_list: thread.join() # Demonstrates that the main process waited for threads to complete print "Done" 

अन्य लोगों की तरह, सीपीआईथॉन केवल I \ O के लिए धागे का उपयोग जीआईएल के कारण इंतजार कर सकता है यदि आप CPU- बद्ध कार्य के लिए एकाधिक कोर से लाभ चाहते हैं, तो मल्टी प्रॉससेसिंग का उपयोग करें:

 from multiprocessing import Process def f(name): print 'hello', name if __name__ == '__main__': p = Process(target=f, args=('bob',)) p.start() p.join() 

एलेक्स मार्टेली के उत्तर ने मेरी मदद की, हालांकि यहां संस्करण को संशोधित किया गया है जिसे मैंने सोचा था कि वह अधिक उपयोगी है (कम से कम मेरे लिए)।

 import Queue import threading import urllib2 worker_data = ['http://google.com', 'http://yahoo.com', 'http://bing.com'] #load up a queue with your data, this will handle locking q = Queue.Queue() for url in worker_data: q.put(url) #define a worker function def worker(queue): queue_full = True while queue_full: try: #get your data off the queue, and do some work url= queue.get(False) data = urllib2.urlopen(url).read() print len(data) except Queue.Empty: queue_full = False #create as many threads as you want thread_count = 5 for i in range(thread_count): t = threading.Thread(target=worker, args = (q,)) t.start() 

मैंने यह बहुत उपयोगी पाया: कोर के रूप में कई धागे बनाते हैं और उन्हें कार्य (बड़ी) की संख्या को कार्यान्वित करते हैं (इस मामले में, एक शेल प्रोग्राम बुलाते हैं):

 import Queue import threading import multiprocessing import subprocess q = Queue.Queue() for i in range(30): #put 30 tasks in the queue q.put(i) def worker(): while True: item = q.get() #execute a task: call a shell program and wait until it completes subprocess.call("echo "+str(item), shell=True) q.task_done() cpus=multiprocessing.cpu_count() #detect number of cores print("Creating %d threads" % cpus) for i in range(cpus): t = threading.Thread(target=worker) t.daemon = True t.start() q.join() #block until all tasks are done 

मेरे लिए, सूत्रण के लिए आदर्श उदाहरण असिंक्रोनस ईवेंट की निगरानी कर रहा है इस कोड को देखें

 # thread_test.py import threading import time class Monitor(threading.Thread): def __init__(self, mon): threading.Thread.__init__(self) self.mon = mon def run(self): while True: if self.mon[0] == 2: print "Mon = 2" self.mon[0] = 3; 

आप एक आईपथाथन सत्र खोलकर और ऐसा करने से इस कोड के साथ खेल सकते हैं:

 >>>from thread_test import Monitor >>>a = [0] >>>mon = Monitor(a) >>>mon.start() >>>a[0] = 2 Mon = 2 >>>a[0] = 2 Mon = 2 

कुछ मिनट तक प्रतीक्षा करें

 >>>a[0] = 2 Mon = 2 

स्टैक पर सभी महान जवाबों और उदाहरणों के साथ-साथ मैंने उपर्युक्त मल्टी प्रॉससेसिंग और थ्रेडींग को व्यक्तिगत रूप से समझने में मदद की है, निम्नलिखित साइट (यहां मैंने इसमें विशेष उदाहरण दिए हैं, क्योंकि उसमें शामिल सरल उदाहरणों के कारण, ऑप ने अनुरोध किया ), वास्तव में मेरे लिए क्लिक किया गया था, इसके दस्तावेज़ीकरण के साथ, और मुझे अजगर के बारे में अभी तक किसी भी प्रश्न के बारे में मेरी समझ है, यह आशा करता है कि यह किसी को यहां जितनी मदद कर सकता है I

  • कोई संबद्धता नहीं है

पायथन थ्रेडिंग

पायथन मल्टीप्रोसेसिंग

हालांकि मैं जवाबों की एक बड़ी संख्या को पहचानता हूं, मुझे लगता है कि यदि मैं किसी और को उनकी रुचि में कुछ की बेहतर समझ प्राप्त करने में मदद कर सकता हूं तो यह संदर्भ के लायक होगा

प्रज्वलित नए समवर्ती फ्यूचर्स मॉड्यूल का उपयोग करना

 def sqr(val): import time time.sleep(0.1) return val * val def process_result(result): print(result) def process_these_asap(tasks): import concurrent.futures with concurrent.futures.ProcessPoolExecutor() as executor: futures = [] for task in tasks: futures.append(executor.submit(sqr, task)) for future in concurrent.futures.as_completed(futures): process_result(future.result()) # Or instead of all this just do: # results = executor.map(sqr, tasks) # list(map(process_result, results)) def main(): tasks = list(range(10)) print('Processing {} tasks'.format(len(tasks))) process_these_asap(tasks) print('Done') return 0 if __name__ == '__main__': import sys sys.exit(main()) 

निष्पादक का दृष्टिकोण उन सभी लोगों से परिचित हो सकता है जिन्होंने जावा के साथ अपने हाथों को गंदा लगाया है।

इसके अलावा एक तरफ ध्यान दें: ब्रह्मांड को समझने के लिए, अपने पूल / निष्पादक को बंद करने के लिए मत भूलें, यदि आप संदर्भ के with प्रयोग नहीं करते हैं (जो कि आपके लिए यह बहुत अच्छा है)

फ़ंक्शन को देखते हुए, यह इस तरह थ्रेड:

 import threading threading.Thread(target=f).start() 

f करने के लिए तर्क पास करने के लिए

 threading.Thread(target=f, args=(a,b,c)).start() 

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

टैलॉक = थ्रेडिंग। बर्थडेसमफोर (मान = 4)

कोड की यह रेखा आप एक समय में प्रक्रियाओं की संख्या को अनुमति दे सकते हैं और शेष थ्रेड को पकड़ कर रख सकते हैं जो बाद में या समाप्त हो चुके पिछले प्रक्रियाओं के बाद चलेंगे।

 import threading import time #tLock = threading.Lock() tLock = threading.BoundedSemaphore(value=4) def timer(name, delay, repeat): print "\r\nTimer: ", name, " Started" tLock.acquire() print "\r\n", name, " has the acquired the lock" while repeat > 0: time.sleep(delay) print "\r\n", name, ": ", str(time.ctime(time.time())) repeat -= 1 print "\r\n", name, " is releaseing the lock" tLock.release() print "\r\nTimer: ", name, " Completed" def Main(): t1 = threading.Thread(target=timer, args=("Timer1", 2, 5)) t2 = threading.Thread(target=timer, args=("Timer2", 3, 5)) t3 = threading.Thread(target=timer, args=("Timer3", 4, 5)) t4 = threading.Thread(target=timer, args=("Timer4", 5, 5)) t5 = threading.Thread(target=timer, args=("Timer5", 0.1, 5)) t1.start() t2.start() t3.start() t4.start() t5.start() print "\r\nMain Complete" if __name__ == "__main__": Main() 

पायथन 3 में समानांतर कार्यों को लॉन्च करने की सुविधा है । यह हमारे काम को आसान बनाता है

इसमें थ्रेड पूलिंग और प्रोसेस पूलिंग है ।

निम्नलिखित एक अंतर्दृष्टि प्रदान करता है:

थ्रेडपूल एक्साक्षक उदाहरण

 import concurrent.futures import urllib.request URLS = ['http://www.foxnews.com/', 'http://www.cnn.com/', 'http://europe.wsj.com/', 'http://www.bbc.co.uk/', 'http://some-made-up-domain.com/'] # Retrieve a single page and report the URL and contents def load_url(url, timeout): with urllib.request.urlopen(url, timeout=timeout) as conn: return conn.read() # We can use a with statement to ensure threads are cleaned up promptly with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: # Start the load operations and mark each future with its URL future_to_url = {executor.submit(load_url, url, 60): url for url in URLS} for future in concurrent.futures.as_completed(future_to_url): url = future_to_url[future] try: data = future.result() except Exception as exc: print('%r generated an exception: %s' % (url, exc)) else: print('%r page is %d bytes' % (url, len(data))) 

ProcessPoolExecutor

 import concurrent.futures import math PRIMES = [ 112272535095293, 112582705942171, 112272535095293, 115280095190773, 115797848077099, 1099726899285419] def is_prime(n): if n % 2 == 0: return False sqrt_n = int(math.floor(math.sqrt(n))) for i in range(3, sqrt_n + 1, 2): if n % i == 0: return False return True def main(): with concurrent.futures.ProcessPoolExecutor() as executor: for number, prime in zip(PRIMES, executor.map(is_prime, PRIMES)): print('%d is prime: %s' % (number, prime)) if __name__ == '__main__': main() 

अधिकांश दस्तावेज़ीकरण और ट्यूटोरियल पायथन के Threading और Queue मॉड्यूल का उपयोग करते हैं, जो वे शुरुआती लोगों के लिए भारी लग सकते हैं।

शायद concurrent.futures.ThreadPoolExecutor विचार। concurrent.futures.ThreadPoolExecutor । अजगर 3 के अजगर के मॉड्यूल। खंड और सूची समझ के with संयुक्त यह एक असली आकर्षण हो सकता है

 from concurrent.futures import ThreadPoolExecutor, as_completed def get_url(url): # Your actual program here. Using threading.Lock() if necessary return "" # List of urls to fetch urls = ["url1", "url2"] with ThreadPoolExecutor(max_workers = 5) as executor: # Creat threads futures = {executor.submit(get_url, url) for url in urls} # as_completed() gives you the threads once finished for f in as_completed(futures): # Get the results rs = f.result() 

यहां, आर्गिक्स तर्क का एक टपल है; किसी भी तर्क को पारित किए बिना फ़ंक्शन कॉल करने के लिए एक खाली ट्यूपल का उपयोग करें। kwargs कीवर्ड तर्क का एक वैकल्पिक शब्दकोश है।

उदाहरण

 #!/usr/bin/python import thread import time # Define a function for the thread def print_time( threadName, delay): count = 0 while count < 5: time.sleep(delay) count += 1 print "%s: %s" % ( threadName, time.ctime(time.time()) ) # Create two threads as follows try: thread.start_new_thread( print_time, ("Thread-1", 2, ) ) thread.start_new_thread( print_time, ("Thread-2", 4, ) ) except: print "Error: unable to start thread" while 1: pass 

जब उपरोक्त कोड निष्पादित होता है, तो यह निम्न परिणाम उत्पन्न करता है –

 Thread-1: Thu Jan 22 15:42:17 2009 Thread-1: Thu Jan 22 15:42:19 2009 Thread-2: Thu Jan 22 15:42:19 2009 Thread-1: Thu Jan 22 15:42:21 2009 Thread-2: Thu Jan 22 15:42:23 2009 Thread-1: Thu Jan 22 15:42:23 2009 Thread-1: Thu Jan 22 15:42:25 2009 Thread-2: Thu Jan 22 15:42:27 2009 Thread-2: Thu Jan 22 15:42:31 2009 Thread-2: Thu Jan 22 15:42:35 2009 

ऊपर दिए गए समाधानों में से कोई भी वास्तव में मेरे जीएनयू / लिनक्स सर्वर पर कई कोर का इस्तेमाल नहीं कर रहा है (जहां मेरे पास व्यवस्थापक अधिकार नहीं हैं)। वे सिर्फ एक कोर पर दौड़ा मैंने कई थ्रेड्स अंडे जाने के लिए निचले स्तर os.fork इंटरफ़ेस का उपयोग किया। यह कोड है जो मेरे लिए काम करता है:

 from os import fork values = ['different', 'values', 'for', 'threads'] for i in range(len(values)): p = fork() if p == 0: my_function(values[i]) break