ใครที่พยายามจะใช้มอดูล asyncio ในไพธอนอาจเจอปัญหาตอนพยายามสั่งรันลูปโดยมีข้อผิดพลาดขึ้นมาในลักษณะว่า
RuntimeError: This event loop is already running
หรืออะไรทำนองนี้ ขึ้นอยู่กับคำสั่งที่ลองใช้ดู แต่ปัญหาโดยรวมก็เกิดจากการที่มีลูปถูกรันอยู่แล้ว จึงทำให้ไม่สามารถสั่งรันลูปเพิ่มได้
ปัญหานี้อาจเกิดเมื่อรันใน spyder (เช่นที่ใช้ใน anaconda) เพราะใน spyder จะมีการรันลูปอยู่ในตัวแล้ว เมื่อพยายามจะรันลูปขึ้นมาอีกก็เลยเจอข้อผิดพลาดซึ่งเตือนว่ารันลูปอยู่แล้ว
เมื่อค้นเกี่ยวกับปัญหานี้ดูก็ได้ไปเจอวิธีที่จะแก้ไขได้ นั่นคือใช้มอดูล nest_asyncio
>>
https://www.cnpython.com/pypi/nest-asyncioมอดูลนี้จะทำให้สามารถรันลูปของ asyncio ได้ แม้ว่าจะใช้ spyder อยู่
สามารถติดตั้งได้ด้วย pip
pip install nest-asyncio
วิธีใช้ก็ง่าย แค่ใส่โค้ดนี้ลงไป หลังจากนั้นก็จะสามารถใช้งานได้
import nest_asyncio
nest_asyncio.apply()
ตัวอย่างการใช้
import asyncio,nest_asyncio,time
nest_asyncio.apply()
async def sawatdilok(s):
print('สวัสดีโลก%s ~ %.6f'%(s,time.time()-t0))
await asyncio.sleep(1)
print('ลาก่อนโลก%s ~ %.6f'%(s,time.time()-t0))
t0 = time.time()
sawa = [sawatdilok('นี้'),sawatdilok('หน้า'),sawatdilok('โน้น')]
asyncio.run(asyncio.gather(*sawa))
ได้
สวัสดีโลกนี้ ~ 0.000146
สวัสดีโลกหน้า ~ 0.000279
สวัสดีโลกโน้น ~ 0.000327
ลาก่อนโลกนี้ ~ 1.002465
ลาก่อนโลกหน้า ~ 1.002754
ลาก่อนโลกโน้น ~ 1.002794
ถ้าหากไม่ได้ใช้ nest_asyncio.apply() ก่อน การรันนี้ก็คงจะเกิดข้อผิดพลาดขึ้นมาเมื่อรันใน spyder ว่า
RuntimeError: asyncio.run() cannot be called from a running event loop
แต่เมื่อใช้แล้วน่าจะสามารถรันออกมาได้ตามปกติ ไม่ติดปัญหาตรงนี้
หรือต่อให้ไม่ได้รันผ่าน spyder ก็ไม่ได้ทำให้เกิดผลอะไรเปลี่ยนแปลง ไปรันจากที่อื่นตามปกติก็ใช้ได้เหมือนกัน
อย่างไรก็ตาม พวกคำสั่งที่ใช้ asyncio แบบนี้รันผ่านคอมมานด์ไลน์โดยตรง แทนที่จะรันผ่าน spyder น่าจะดีกว่า