我的环境是Python2.7。我非常模糊,我运行了apply_async(test_func),我让test_func打印当前的process_name。如:
q = Queue(maxsize=20) #multiprocessing.Queue
def test_func(queue):
print 'Process'
print multiprocessing.current_process()
if __name__ == '__main__':
pool = Pool(processes=3)
for i in xrange(3):
pool.apply_async(test_func(q,))
while True:
time.sleep(1)
if q.empty():
break
print 'Main Process Monitoring'
print multiprocessing.current_process()
代码没有语法错误,终端始终打印<MainProcess>
如果我更改pool.apply_async(test_func,(q,))(add a comma)
,则无法进入test_func
,就像完成循环一样,只打印'Main Process Monitoring' <MainProcess>
..
所以我无法理解为什么apply_async()
无法正常工作,当它工作时,它会以MainProcess
运行,而我已尝试过pool.close(),pool.join()
。 。
如果有人可以提供帮助。非常感谢!
答案 0 :(得分:1)
首先,您的test_func
函数没有return
语句,因此返回None
:
def test_func(queue):
print 'Process'
print multiprocessing.current_process()
将其插入交互式Python:
>>> import multiprocessing
>>> x = test_func(None)
Process
<_MainProcess(MainProcess, started)>
>>> print x
None
这意味着:
pool.apply_async(test_func(q,))
使用参数test_func
调用(q,)
,返回None
;然后你将None
传递给pool.apply_async
。
The multiprocessing
documentation将apply_async
描述为调用其第一个参数a la apply
,但是异步,即不等待其结果。让我们以交互方式尝试apply(None)
,看看它是做什么的:
>>> apply(none)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable
所以我们可能期望apply_async
引发一个TypeError--事实上, 它的作用是什么,但错误是推迟到我们试图得到结果之前:
>>> pool = multiprocessing.Pool(processes=3)
>>> pool.apply_async(None)
<multiprocessing.pool.ApplyResult object at 0x801b27510>
让我们抓住这个ApplyResult对象,以便我们可以使用和检查它(特殊名称_
保存交互期间返回的最新值):
>>> x = _
现在我们可以看到异步应用是否对我们有效:
>>> x.ready()
True
确实如此! (如果没有,我们可以调用x.wait()
等待它,但由于现在已经准备就绪,让我们按下。)结果是常规值还是异常?
>>> x.successful()
False
啊,结果是一个例外。我们得到例外:
>>> x.get()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/multiprocessing/pool.py", line 567, in get
raise self._value
TypeError: 'NoneType' object is not callable
我们得到了答案:将None
传递给apply_async
旋转执行函数None
(毕竟这不是函数),并且一旦我们收集了最终结果结果,结果是我们期望的例外。
如果我更改
pool.apply_async(test_func,(q,))
(添加逗号),则无法进入test_func
...
让我们在交互式解释器中尝试类似的东西。我没有q
,但由于test_func
实际上并没有使用它的参数,所以我们可以通过无:
>>> x = pool.apply_async(test_func, (None,))
>>> Process
<Process(PoolWorker-2, started daemon)>
这个输出有点乱,但看起来确实有效。让我们看看x
是否有结果,以及它是否成功,以及结果如何:
x.ready()
True
>>> x.successful()
True
>>> x.get()
>>>
(第一个>>>
提示似乎丢失了,但它实际上只是被test_func
中打印的内容打印出来了。有一个成功的价值,但由于它是无,解释器在这里没有打印任何东西 - 我们必须完成print x.get()
才能看到它。
换句话说,如果你打算使用apply_async
,你必须(1)在某处保存旋转的“待定结果”,然后(2)使用.get()
实际检索结果。您还需要从函数中返回一些内容。
同时这个循环:
while True:
time.sleep(1)
if q.empty():
break
print 'Main Process Monitoring'
print multiprocessing.current_process()
永远不会一直运行,因为你的队列对象q
在你测试它时是是空的,所以你立即break
了。
答案 1 :(得分:0)
偶尔,我知道我应该使用fname = raw_input("Enter file name: ")
fh = open(fname)
lst = list()
for line in fh:
word = line.split()
for item in word:
if item not in lst:
lst.append(item)
lst.sort()
print(lst)
,这对我来说是个错误。
但奇怪的是,当我使用apply_async(test_func, (i,))
时,它将无效。apply_async(test_func, (q,))
是多处理.Queue()。如果我删除它或替换除Queue对象之外的任何其他对象,它会工作(正常打印子过程)
我不知道队列是否有某些错误或其他什么问题......
有人知道吗?非常感谢!