Python Language
बहु सूत्रण
खोज…
परिचय
थ्रेड्स पायथन कार्यक्रमों को एक साथ कई कार्यों को संभालने की अनुमति देते हैं, ताकि व्यक्तिगत रूप से आदेशों के क्रम को चलाने का विरोध किया जा सके। यह विषय थ्रेडिंग के पीछे के सिद्धांतों की व्याख्या करता है और इसके उपयोग को प्रदर्शित करता है।
मल्टीथ्रेडिंग की मूल बातें
threading
मॉड्यूल का उपयोग करके, एक नया threading.Thread
बनाकर निष्पादन का एक नया सूत्र शुरू किया जा सकता है। इसे चलाने और इसे निष्पादित करने के लिए एक फ़ंक्शन असाइन करें:
import threading
def foo():
print "Hello threading!"
my_thread = threading.Thread(target=foo)
target
पैरामीटर फ़ंक्शन (या कॉल करने योग्य ऑब्जेक्ट) को चलाने के लिए संदर्भित करता है। Thread
ऑब्जेक्ट पर start
होने तक थ्रेड निष्पादन शुरू नहीं करेगा।
एक धागा शुरू करना
my_thread.start() # prints 'Hello threading!'
अब जब कि my_thread
समाप्त हो गया है और समाप्त, बुला start
फिर से एक का उत्पादन करेगा RuntimeError
। यदि आप अपने धागे को एक डेमन के रूप में चलाना चाहते हैं, तो daemon=True
पार करना daemon=True
कर्व, या कॉलिंग start()
होने से पहले my_thread.daemon
को True
start()
, आपके Thread
को डेमन के रूप में बैकग्राउंड में चुपचाप चलाने का कारण बनता है।
एक सूत्र में जुड़ना
ऐसे मामलों में जहां आप एक बड़ी नौकरी को कई छोटे लोगों में विभाजित करते हैं और उन्हें समवर्ती रूप से चलाना चाहते हैं, लेकिन जारी रखने से पहले उन सभी को समाप्त करने के लिए प्रतीक्षा करने की आवश्यकता होती है, Thread.join()
वह विधि है जिसकी आप तलाश कर रहे हैं।
उदाहरण के लिए, मान लें कि आप किसी वेबसाइट के कई पेज डाउनलोड करना चाहते हैं और उन्हें एक पेज में संकलित करना चाहते हैं। आप ऐसा करेंगे:
import requests
from threading import Thread
from queue import Queue
q = Queue(maxsize=20)
def put_page_to_q(page_num):
q.put(requests.get('http://some-website.com/page_%s.html' % page_num)
def compile(q):
# magic function that needs all pages before being able to be executed
if not q.full():
raise ValueError
else:
print("Done compiling!")
threads = []
for page_num in range(20):
t = Thread(target=requests.get, args=(page_num,))
t.start()
threads.append(t)
# Next, join all threads to make sure all threads are done running before
# we continue. join() is a blocking call (unless specified otherwise using
# the kwarg blocking=False when calling join)
for t in threads:
t.join()
# Call compile() now, since all threads have completed
compile(q)
कैसे join()
काम करता है पर एक करीब देखो यहाँ पाया जा सकता है ।
एक कस्टम थ्रेड क्लास बनाएँ
threading.Thread
का उपयोग करना। threading.Thread
क्लास का उपयोग करके हम नए कस्टम थ्रेड क्लास को हटा सकते हैं। हमें एक उपवर्ग में run
विधि को ओवरराइड करना चाहिए।
from threading import Thread
import time
class Sleepy(Thread):
def run(self):
time.sleep(5)
print("Hello form Thread")
if __name__ == "__main__":
t = Sleepy()
t.start() # start method automatic call Thread class run method.
# print 'The main program continues to run in foreground.'
t.join()
print("The main program continues to run in the foreground.")
धागे के बीच संवाद
आपके कोड में कई थ्रेड हैं और आपको उनके बीच सुरक्षित रूप से संवाद करने की आवश्यकता है।
आप queue
लाइब्रेरी से Queue
उपयोग कर सकते हैं।
from queue import Queue
from threading import Thread
# create a data producer
def producer(output_queue):
while True:
data = data_computation()
output_queue.put(data)
# create a consumer
def consumer(input_queue):
while True:
# retrieve data (blocking)
data = input_queue.get()
# do something with the data
# indicate data has been consumed
input_queue.task_done()
एक साझा कतार के साथ निर्माता और उपभोक्ता धागे बनाना
q = Queue()
t1 = Thread(target=consumer, args=(q,))
t2 = Thread(target=producer, args=(q,))
t1.start()
t2.start()
वर्कर पूल बनाना
threading
और queue
का उपयोग करना:
from socket import socket, AF_INET, SOCK_STREAM
from threading import Thread
from queue import Queue
def echo_server(addr, nworkers):
print('Echo server running at', addr)
# Launch the client workers
q = Queue()
for n in range(nworkers):
t = Thread(target=echo_client, args=(q,))
t.daemon = True
t.start()
# Run the server
sock = socket(AF_INET, SOCK_STREAM)
sock.bind(addr)
sock.listen(5)
while True:
client_sock, client_addr = sock.accept()
q.put((client_sock, client_addr))
echo_server(('',15000), 128)
concurrent.futures.Threadpoolexecutor
का उपयोग करना।
from socket import AF_INET, SOCK_STREAM, socket
from concurrent.futures import ThreadPoolExecutor
def echo_server(addr):
print('Echo server running at', addr)
pool = ThreadPoolExecutor(128)
sock = socket(AF_INET, SOCK_STREAM)
sock.bind(addr)
sock.listen(5)
while True:
client_sock, client_addr = sock.accept()
pool.submit(echo_client, client_sock, client_addr)
echo_server(('',15000))
डेविड बेज़ले और ब्रायन के। जोन्स (ओ'रिली) द्वारा पायथन कुकबुक, तीसरा संस्करण। कॉपीराइट 2013 डेविड बेज़ले और ब्रायन जोन्स, 978-1-449-34037-7।
मल्टीथ्रेड्स का उन्नत उपयोग
इस अनुभाग में मल्टीथ्रेडिंग का उपयोग करके महसूस किए गए कुछ सबसे उन्नत उदाहरण होंगे।
उन्नत प्रिंटर (लकड़हारा)
एक धागा जो सब कुछ प्राप्त करता है और टर्मिनल चौड़ाई के अनुसार आउटपुट को संशोधित करता है। अच्छा हिस्सा यह है कि टर्मिनल की चौड़ाई में बदलाव होने पर "पहले से लिखा हुआ" आउटपुट भी संशोधित हो जाता है।
#!/usr/bin/env python2
import threading
import Queue
import time
import sys
import subprocess
from backports.shutil_get_terminal_size import get_terminal_size
printq = Queue.Queue()
interrupt = False
lines = []
def main():
ptt = threading.Thread(target=printer) # Turn the printer on
ptt.daemon = True
ptt.start()
# Stupid example of stuff to print
for i in xrange(1,100):
printq.put(' '.join([str(x) for x in range(1,i)])) # The actual way to send stuff to the printer
time.sleep(.5)
def split_line(line, cols):
if len(line) > cols:
new_line = ''
ww = line.split()
i = 0
while len(new_line) <= (cols - len(ww[i]) - 1):
new_line += ww[i] + ' '
i += 1
print len(new_line)
if new_line == '':
return (line, '')
return (new_line, ' '.join(ww[i:]))
else:
return (line, '')
def printer():
while True:
cols, rows = get_terminal_size() # Get the terminal dimensions
msg = '#' + '-' * (cols - 2) + '#\n' # Create the
try:
new_line = str(printq.get_nowait())
if new_line != '!@#EXIT#@!': # A nice way to turn the printer
# thread out gracefully
lines.append(new_line)
printq.task_done()
else:
printq.task_done()
sys.exit()
except Queue.Empty:
pass
# Build the new message to show and split too long lines
for line in lines:
res = line # The following is to split lines which are
# longer than cols.
while len(res) !=0:
toprint, res = split_line(res, cols)
msg += '\n' + toprint
# Clear the shell and print the new output
subprocess.check_call('clear') # Keep the shell clean
sys.stdout.write(msg)
sys.stdout.flush()
time.sleep(.5)
थोड़ी देर लूप के साथ स्टॉपेबल थ्रेड
import threading
import time
class StoppableThread(threading.Thread):
"""Thread class with a stop() method. The thread itself has to check
regularly for the stopped() condition."""
def __init__(self):
super(StoppableThread, self).__init__()
self._stop_event = threading.Event()
def stop(self):
self._stop_event.set()
def join(self, *args, **kwargs):
self.stop()
super(StoppableThread,self).join(*args, **kwargs)
def run()
while not self._stop_event.is_set():
print("Still running!")
time.sleep(2)
print("stopped!"
इस प्रश्न पर आधारित