में थ्रेडपूल में प्रक्रियाओं को रोकना मैं कुछ हार्डवेयर को नियंत्रित करने वाली लाइब्रेरी के लिए एक इंटरैक्टिव रैपर (ipython में उपयोग के लिए) लिखने की कोशिश कर रहा हूं। कुछ कॉल आईओ पर भारी हैं इसलिए कार्यों को समानांतर में करने के लिए समझ में आता है। एक ThreadPool (लगभग) का उपयोग अच्छी तरह से काम करता है:पायथन
from multiprocessing.pool import ThreadPool
class hardware():
def __init__(IPaddress):
connect_to_hardware(IPaddress)
def some_long_task_to_hardware(wtime):
wait(wtime)
result = 'blah'
return result
pool = ThreadPool(processes=4)
Threads=[]
h=[hardware(IP1),hardware(IP2),hardware(IP3),hardware(IP4)]
for tt in range(4):
task=pool.apply_async(h[tt].some_long_task_to_hardware,(1000))
threads.append(task)
alive = [True]*4
Try:
while any(alive) :
for tt in range(4): alive[tt] = not threads[tt].ready()
do_other_stuff_for_a_bit()
except:
#some command I cannot find that will stop the threads...
raise
for tt in range(4): print(threads[tt].get())
समस्या आता उपयोगकर्ता प्रक्रिया को रोकने के लिए करना चाहता है या वहाँ do_other_stuff_for_a_bit()
में एक आईओ त्रुटि है यदि। दबाकर Ctrl + सी मुख्य प्रक्रिया को रोकता है लेकिन कार्यकर्ता धागे तब तक चलते रहते हैं जब तक उनका वर्तमान कार्य पूरा न हो जाए।
लाइब्रेरी को फिर से लिखने के बिना इन थ्रेड को रोकने के लिए कोई तरीका है या उपयोगकर्ता को पायथन से बाहर निकलना है? pool.terminate()
और pool.join()
जो मैंने अन्य उदाहरणों में उपयोग किया है, वे नौकरी नहीं लगते हैं।
वास्तविक दिनचर्या (उपरोक्त सरलीकृत संस्करण की बजाय) लॉगिंग का उपयोग करता है और हालांकि सभी कार्यकर्ता धागे किसी बिंदु पर बंद हो जाते हैं, मैं उन प्रक्रियाओं को देख सकता हूं जिन्हें उन्होंने पूरा करना जारी रखा है (और हार्डवेयर होने के नाते मैं देख सकता हूं कमरे में देखकर उनका प्रभाव)।
यह अजगर 2.7 में है।
अद्यतन:
समाधान एक धागा पूल के बजाय multiprocessing.Process उपयोग पर स्विच करना हो रहा है। परीक्षण कोड मैंने कोशिश की foo_pulse चलाने के लिए है: आप ThreadPool का उपयोग कर तो Ctrl-C चल (भले ही यह सूत्र सही दूर मारने करता से foo_pulse नहीं रुकती इस चल कोशिश तो
class foo(object):
def foo_pulse(self,nPulse,name): #just one method of *many*
print('starting pulse for '+name)
result=[]
for ii in range(nPulse):
print('on for '+name)
time.sleep(2)
print('off for '+name)
time.sleep(2)
result.append(ii)
return result,name
, प्रिंट बयान पर रखने आने वाले:
from multiprocessing.pool import ThreadPool
import time
def test(nPulse):
a=foo()
pool=ThreadPool(processes=4)
threads=[]
for rn in range(4) :
r=pool.apply_async(a.foo_pulse,(nPulse,'loop '+str(rn)))
threads.append(r)
alive=[True]*4
try:
while any(alive) : #wait until all threads complete
for rn in range(4):
alive[rn] = not threads[rn].ready()
time.sleep(1)
except : #stop threads if user presses ctrl-c
print('trying to stop threads')
pool.terminate()
print('stopped threads') # this line prints but output from foo_pulse carried on.
raise
else :
for t in threads : print(t.get())
हालांकि multiprocessing.Process का उपयोग कर एक संस्करण में काम करता है के रूप में उम्मीद:
import multiprocessing as mp
import time
def test_pro(nPulse):
pros=[]
ans=[]
a=foo()
for rn in range(4) :
q=mp.Queue()
ans.append(q)
r=mp.Process(target=wrapper,args=(a,"foo_pulse",q),kwargs={'args':(nPulse,'loop '+str(rn))})
r.start()
pros.append(r)
try:
for p in pros : p.join()
print('all done')
except : #stop threads if user stops findRes
print('trying to stop threads')
for p in pros : p.terminate()
print('stopped threads')
else :
print('output here')
for q in ans :
print(q.get())
print('exit time')
मैं पुस्तकालय foo के लिए एक आवरण कहाँ परिभाषित किया है (ताकि यह किया फिर से लिखे जाने की जरूरत नहीं है)।
def wrapper(a,target,q,args=(),kwargs={}):
'''Used when return value is wanted'''
q.put(getattr(a,target)(*args,**kwargs))
प्रलेखन मैं कोई कारण नहीं क्यों एक पूल कार्य नहीं करेगा (एक बग के अलावा अन्य) को देखने से: वापसी मान की जरूरत नहीं है, तो न तो इस आवरण है।
क्या आपके पास अनियंत्रित वर्गों का उपयोग करने का कोई कारण है? आपको 'concurrent.futures' मॉड्यूल के साथ शायद बेहतर भाग्य होगा। – SuperSaiyan
अनियंत्रित वर्गों का उपयोग करने के लिए कोई वास्तविक कारण नहीं है - इसके अलावा, उदाहरण के कोड में जो कुछ भी किया गया था, उसमें इस्तेमाल किया गया था जब यह शोध किया गया था। – SRD
@SuperSaiyan: यह एक अलग नाम के तहत दस्तावेज है; 'थ्रेडपूल' को 'multiprocessing.dummy.Pool' के तहत एक प्रलेखित फैशन में उजागर किया गया है, जहां ['multiprocessing.dummy' प्रक्रियाओं के बजाय थ्रेड द्वारा समर्थित' मल्टीप्रोसेसिंग 'एपीआई की एक करीबी प्रति है] (https: // docs। python.org/3/library/multiprocessing.html#module-multiprocessing.dummy)। – ShadowRanger