【发布时间】:2017-03-02 03:08:10
【问题描述】:
大家晚上好,我正在尝试创建互联网机器人,但在将脚本从 python 3.4 迁移到 3.5 或 3.6+ 时遇到了问题。它使用 asyncio 并且在 3.4 python 上运行良好,但是当我使用 python3.5+ 启动它时出现错误:RuntimeError: Cannot run the event loop while another loop is running
这里是代码方案:
import multiprocessing as mp
import asyncio
import concurrent.futures
import aiohttp
def create_proccesses(separate_loop_creator, coro):
proccesses = []
for n in range(2):
proc = mp.Process(target=separate_loop_creator, args=(coro,))
proc.start()
proccesses.append(proc)
for p in proccesses:
p.join()
def separate_loop_creator(coro):
sep_loop = asyncio.new_event_loop()
asyncio.set_event_loop(sep_loop)
tasks = [asyncio.async(coro(sep_loop)) for _ in range(100)]
try:
sep_loop.run_until_complete(asyncio.wait(tasks))
sep_loop.close()
except Exception as err:
print(err)
for task in tasks:
task.cancel()
sep_loop.close()
@asyncio.coroutine
def manager(exe, loop):
# some calculations and start coros in several processes
loop.run_in_executor(
exe,
create_proccesses,
separate_loop_creator,
some_coro
)
@asyncio.coroutine
def some_work_in_mainloop():
while True:
print('Some server dealing with connections here...')
yield from asyncio.sleep(1)
@asyncio.coroutine
def some_coro(loop):
with aiohttp.ClientSession(loop=loop) as session:
response = yield from session.get('http://google.com')
yield from asyncio.sleep(2)
print(response.status)
if __name__ == '__main__':
mainloop = asyncio.get_event_loop()
executor = concurrent.futures.ProcessPoolExecutor(5)
asyncio.async(some_work_in_mainloop())
asyncio.async(manager(executor, mainloop))
try:
mainloop.run_forever()
finally:
mainloop.close()
separate_loop_creator() 协程中引发的异常是RuntimeError: Cannot run the event loop while another loop is running。我认为这是因为更改了get_event_loop() mechnics,但我不明白我的代码有什么问题。
这是我想做的:
+--------------+
+-------+other service |
+----------+ +--------------+
| mainloop |
+----------+
| +------------+
+-----+ executor |
+------+-----+
|
+------+--------+
|start proccess |
+---+-------+---+
+-----------------+ | | +---------------+
|start new loop +------+ +------+ start new loop|
+--------+--------+ +-------+-------+
| |
+-------+-------+ +------v-------+
| run coro | | run coro |
+---------------+ +--------------+
这是我在 python3.5.3 上得到的跟踪:
Traceback (most recent call last):
File "tst.py", line 21, in separate_loop_creator
sep_loop.run_until_complete(asyncio.wait(tasks))
File "/root/.pyenv/versions/3.5.3/lib/python3.5/asyncio/base_events.py", line 454, in run_until_complete
self.run_forever()
File "/root/.pyenv/versions/3.5.3/lib/python3.5/asyncio/base_events.py", line 411, in run_forever
'Cannot run the event loop while another loop is running')
RuntimeError: Cannot run the event loop while another loop is running
Cannot run the event loop while another loop is running
Traceback (most recent call last):
File "tst.py", line 21, in separate_loop_creator
sep_loop.run_until_complete(asyncio.wait(tasks))
File "/root/.pyenv/versions/3.5.3/lib/python3.5/asyncio/base_events.py", line 454, in run_until_complete
self.run_forever()
File "/root/.pyenv/versions/3.5.3/lib/python3.5/asyncio/base_events.py", line 411, in run_forever
'Cannot run the event loop while another loop is running')
RuntimeError: Cannot run the event loop while another loop is running
Python 3.4.3 结果:
...
200
Some server dealing with connections here...
200
200
Some server dealing with connections here...
200
200
Some server dealing with connections here...
200
...
【问题讨论】:
标签: python python-3.4 python-3.5 python-multiprocessing python-asyncio