Python Language
प्रक्रियाएं और सूत्र
खोज…
परिचय
अधिकांश कार्यक्रमों को लाइन द्वारा लाइन निष्पादित किया जाता है, केवल एक बार में एक ही प्रक्रिया चल रही है। थ्रेड्स कई प्रक्रियाओं को एक दूसरे से स्वतंत्र प्रवाह करने की अनुमति देते हैं। कई प्रोसेसर के साथ थ्रेडिंग प्रोग्राम को कई प्रक्रियाओं को एक साथ चलाने की अनुमति देता है। यह विषय पायथन में धागे के कार्यान्वयन और उपयोग का दस्तावेज है।
ग्लोबल इंटरप्रेटर लॉक
ग्लोबल इंटरप्रेटर लॉक के कारण पाइथन मल्टीथ्रेडिंग प्रदर्शन अक्सर पीड़ित हो सकता है। संक्षेप में, भले ही आप पायथन प्रोग्राम में कई थ्रेड्स हो सकते हैं, केवल एक बायोटेक निर्देश सीपीयू की संख्या की परवाह किए बिना, किसी भी समय समानांतर में निष्पादित कर सकता है।
जैसे, उन मामलों में मल्टीथ्रेडिंग जहां ऑपरेशन बाहरी घटनाओं द्वारा अवरुद्ध होते हैं - जैसे नेटवर्क पहुंच - काफी प्रभावी हो सकते हैं:
import threading
import time
def process():
time.sleep(2)
start = time.time()
process()
print("One run took %.2fs" % (time.time() - start))
start = time.time()
threads = [threading.Thread(target=process) for _ in range(4)]
for t in threads:
t.start()
for t in threads:
t.join()
print("Four runs took %.2fs" % (time.time() - start))
# Out: One run took 2.00s
# Out: Four runs took 2.00s
ध्यान दें कि भले ही प्रत्येक process
को निष्पादित करने में 2 सेकंड लगे हों, लेकिन चार प्रक्रियाएं एक साथ समानांतर रूप से चलने में सक्षम थीं, कुल 2 सेकंड लेती हैं।
हालाँकि, ऐसे मामलों में बहु-सूत्रण जहां पाइथन कोड में सघन संगणनाएँ की जा रही हैं - जैसे कि बहुत संगणना - जिसके परिणामस्वरूप बहुत सुधार नहीं होता है, और समानांतर में चलने की तुलना में धीमा भी हो सकता है:
import threading
import time
def somefunc(i):
return i * i
def otherfunc(m, i):
return m + i
def process():
for j in range(100):
result = 0
for i in range(100000):
result = otherfunc(result, somefunc(i))
start = time.time()
process()
print("One run took %.2fs" % (time.time() - start))
start = time.time()
threads = [threading.Thread(target=process) for _ in range(4)]
for t in threads:
t.start()
for t in threads:
t.join()
print("Four runs took %.2fs" % (time.time() - start))
# Out: One run took 2.05s
# Out: Four runs took 14.42s
बाद के मामले में, मल्टीप्रोसेसिंग कई प्रक्रियाओं के रूप में प्रभावी हो सकती है, ज़ाहिर है, एक साथ कई निर्देशों को निष्पादित कर सकती है:
import multiprocessing
import time
def somefunc(i):
return i * i
def otherfunc(m, i):
return m + i
def process():
for j in range(100):
result = 0
for i in range(100000):
result = otherfunc(result, somefunc(i))
start = time.time()
process()
print("One run took %.2fs" % (time.time() - start))
start = time.time()
processes = [multiprocessing.Process(target=process) for _ in range(4)]
for p in processes:
p.start()
for p in processes:
p.join()
print("Four runs took %.2fs" % (time.time() - start))
# Out: One run took 2.07s
# Out: Four runs took 2.30s
मल्टीपल थ्रेड में चल रहा है
किसी थ्रेड में फ़ंक्शन चलाने के लिए threading.Thread
का उपयोग करें।
import threading
import os
def process():
print("Pid is %s, thread id is %s" % (os.getpid(), threading.current_thread().name))
threads = [threading.Thread(target=process) for _ in range(4)]
for t in threads:
t.start()
for t in threads:
t.join()
# Out: Pid is 11240, thread id is Thread-1
# Out: Pid is 11240, thread id is Thread-2
# Out: Pid is 11240, thread id is Thread-3
# Out: Pid is 11240, thread id is Thread-4
कई प्रक्रियाओं में चल रहा है
किसी अन्य प्रक्रिया में फ़ंक्शन चलाने के लिए multiprocessing.Process
का उपयोग करें। इंटरफ़ेस threading.Thread
समान है।
import multiprocessing
import os
def process():
print("Pid is %s" % (os.getpid(),))
processes = [multiprocessing.Process(target=process) for _ in range(4)]
for p in processes:
p.start()
for p in processes:
p.join()
# Out: Pid is 11206
# Out: Pid is 11207
# Out: Pid is 11208
# Out: Pid is 11209
धागे के बीच राज्य साझा करना
जैसा कि सभी थ्रेड्स एक ही प्रक्रिया में चल रहे हैं, सभी थ्रेड्स में समान डेटा तक पहुंच है।
हालांकि, सिंक्रनाइज़ेशन मुद्दों से बचने के लिए साझा डेटा के समवर्ती उपयोग को लॉक के साथ संरक्षित किया जाना चाहिए।
import threading
obj = {}
obj_lock = threading.Lock()
def objify(key, val):
print("Obj has %d values" % len(obj))
with obj_lock:
obj[key] = val
print("Obj now has %d values" % len(obj))
ts = [threading.Thread(target=objify, args=(str(n), n)) for n in range(4)]
for t in ts:
t.start()
for t in ts:
t.join()
print("Obj final result:")
import pprint; pprint.pprint(obj)
# Out: Obj has 0 values
# Out: Obj has 0 values
# Out: Obj now has 1 values
# Out: Obj now has 2 valuesObj has 2 values
# Out: Obj now has 3 values
# Out:
# Out: Obj has 3 values
# Out: Obj now has 4 values
# Out: Obj final result:
# Out: {'0': 0, '1': 1, '2': 2, '3': 3}
प्रक्रियाओं के बीच राज्य साझा करना
विभिन्न प्रक्रियाओं में चल रहे कोड, डिफ़ॉल्ट रूप से, समान डेटा साझा नहीं करते हैं। हालाँकि, multiprocessing
मॉड्यूल में कई प्रक्रियाओं में मूल्यों को साझा करने में मदद करने के लिए प्राइमेटिव होते हैं।
import multiprocessing
plain_num = 0
shared_num = multiprocessing.Value('d', 0)
lock = multiprocessing.Lock()
def increment():
global plain_num
with lock:
# ordinary variable modifications are not visible across processes
plain_num += 1
# multiprocessing.Value modifications are
shared_num.value += 1
ps = [multiprocessing.Process(target=increment) for n in range(4)]
for p in ps:
p.start()
for p in ps:
p.join()
print("plain_num is %d, shared_num is %d" % (plain_num, shared_num.value))
# Out: plain_num is 0, shared_num is 4