खोज…


परिचय

अधिकांश कार्यक्रमों को लाइन द्वारा लाइन निष्पादित किया जाता है, केवल एक बार में एक ही प्रक्रिया चल रही है। थ्रेड्स कई प्रक्रियाओं को एक दूसरे से स्वतंत्र प्रवाह करने की अनुमति देते हैं। कई प्रोसेसर के साथ थ्रेडिंग प्रोग्राम को कई प्रक्रियाओं को एक साथ चलाने की अनुमति देता है। यह विषय पायथन में धागे के कार्यान्वयन और उपयोग का दस्तावेज है।

ग्लोबल इंटरप्रेटर लॉक

ग्लोबल इंटरप्रेटर लॉक के कारण पाइथन मल्टीथ्रेडिंग प्रदर्शन अक्सर पीड़ित हो सकता है। संक्षेप में, भले ही आप पायथन प्रोग्राम में कई थ्रेड्स हो सकते हैं, केवल एक बायोटेक निर्देश सीपीयू की संख्या की परवाह किए बिना, किसी भी समय समानांतर में निष्पादित कर सकता है।

जैसे, उन मामलों में मल्टीथ्रेडिंग जहां ऑपरेशन बाहरी घटनाओं द्वारा अवरुद्ध होते हैं - जैसे नेटवर्क पहुंच - काफी प्रभावी हो सकते हैं:

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



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow