我有一个由for循环组成的函数,它需要很长时间来处理每个元素。
在这个循环中我只关心如果我找到一个结果或者没有结果,那么循环的执行顺序无关紧要。
如果没有找到结果,它只需要处理所有元素。
我的代码看起来像这样:
import random
from time import sleep
class Elements:
def __init__(self,id):
self.id = id
def analyze(self,result):
sleep(random.random()/2)
if result > 0.9:
return True
def get_result(self):
sleep(random.random()/2)
return random.random()
def long_process(element):
result = element.get_result()
print element.id,result
if element.analyze(result) == True:
return element, result
results.append(result)
if __name__ == '__main__':
elements = []
for n in xrange(10):
elements.append(Elements(n))
results = []
desired = None
for element in elements:
desired = long_process(element)
if desired:
break
if desired:
print desired
else:
print sorted(results,reverse=True)[0]
如果找到元素中的所需元素,则输出:
0 0.150771147344
1 0.510095601312
2 0.28908099464
3 0.410008760093
4 0.435872688389
5 0.960307534462
(<__main__.Elements instance at 0x02311AD0>, 0.9603075344618438)
如果没有,它会说出来:
0 0.361404239639
1 0.207105823026
2 0.851923103243
3 0.720462633138
4 0.58273657804
5 0.380394809851
6 0.590615590942
7 0.130172801534
8 0.57736519194
9 0.597338819896
0.851923103243 # the best element
我正在尝试使用多处理池来处理单独线程中的每个元素。但是我没有达到预期的效果。
这是我尝试过的。
def long_process(element):
result = element.get_result()
print element.id,result, element.analyze(result)
if element.analyze(result) == True:
return element, result
results.append(result)
if __name__ == '__main__':
# freeze_support()
pool = Pool(processes=2)
results = []
pool.imap_unordered(long_process,elements)
pool.close()
pool.join()
print sorted(results)[0]
输出:
0 0.257371095047 None
1 0.8533933601 None
2 0.74433029726 None
3 0.138217827732 None
5 1 True
6 0.961344251697 True
4 0.0664381718173 None
7 0.000891701766875 None
9 1 True
8 0.771957314202 None
Traceback (most recent call last):
File "C:/User/user/Documents/Python/threading_test.py", line 40, in <module>
print sorted(results)[0]
IndexError: list index out of range
但这有两个问题:
它确实以无序顺序工作(id 2,3,5,6,4 ...),它得到的结果,但是当分析为真(5 1真)时它不会停止, 并且都没有将结果附加到结果列表。[IndexError]
我尝试使用Pool.apply_async,但我也无法获取结果。
答案 0 :(得分:0)
使用代码很难,所以我使用apply_async
做了一个非常简单的函数示例:
from multiprocessing.pool import Pool
# habit, you can use a flag instead ...
from threading import Event
import sys
# tell everyone we're done
done = Event()
# aggregate results here
results = []
success = []
每个进程都返回一个结果,无论如何:
def is7(x):
if x == 7:
return (x, True, )
return x
这是对每个结果应用的回调,在apply_async
的结果返回时使用
def handle_result(x):
if type(x) is tuple:
# a tuple is necessarily the result we want, so we're done here.
done.set()
# stop pool
p.terimnate()
success.append(x)
return
results.append(x)
这是我们遍历项目(其中1000个)并在每个项目上应用函数is7
的地方。如果他们中的任何人找到了解决方案,我们会立即停止并通知
p = Pool()
def run_processes():
for element in range(0, 1000):
print "trying %s" % str(element)
p.apply_async(func=is7, args=(element,), callback=handle_result)
# wait for completion
p.close()
p.join()
# start dispatchig tasks to pool
run_processes()
if done.isSet():
# result may contain more than one, if two success tasks were executed closely
print "Found result: %s" % str(success)
else:
print "No results found, here is the list: %s " % str(results)
注意:无法保证循环将在7处完全停止,因为异步调度任务,它可能会在7之后停止一些项目。