← index #8340Issue #13288
Related · high · value 0.114
QUERY · ISSUE

Using asyncio in _thread

openby yjchunopened 2022-02-22updated 2022-03-29
extmod

Hello.
This might be a feature request: asyncio is missing support for threading

import uasyncio as asyncio
import _thread
import time


async def test1(arg):
    try:
        while True:
            print(arg)
            await asyncio.sleep(1)

    except Exception as e:
        print('Exception in '+arg)
        print(e)


def run(arg):
    try:
        asyncio.run(test1(arg))
    except Exception as e:
        print('Exception in asyncio.run ' + arg)
        print(e)
    print("END "+arg)


_thread.start_new_thread(run, ('core1',))
time.sleep_ms(100)
run('core0')

Tested in two ports: unix with uasyncio module included and rp2 with https://github.com/micropython/micropython/pull/8310 patch
Exception within a few seconds in both ports.
Sometimes ValueError: generator already executing
Sometimes 'NoneType' object has no attribute 'ph_child'

Also I would like to create new event loop in new thread (which is automatically done in CPython). Do you think it is possible to implement proper event loop? or would there be limitations in VM? (is generator is thread safe in VM level?)

CANDIDATE · ISSUE

V1.22 creating new thread leads to hangup

closedby TRadigkopened 2023-12-28updated 2024-06-03
bug

Dear micropython developers,

this morning I found about micropython V1.22 and tried this on my Raspberry Pico (non W). But unfortunately I had to find out that my programs stop when the second thread is created.

consider this boot.py to reproduce the issue:

import _thread
import machine 
import asyncio

from time import sleep, sleep_ms


async def thread1task():
    print("thread 1 started")
    while True:
        print("thread 1 talking ... ")
        await asyncio.sleep(1)
        
def thread2task():
    print("thread 2 started")
    while True:
        print("thread 2 talking ... ")
        sleep(1)


if __name__ == "__main__":
    try:
        loop = asyncio.get_event_loop()
        messagestart = const(">> starting script in ... ")
        print(messagestart + f"3")
        sleep(1)
        print(messagestart + f"2")
        sleep(1)
        print(messagestart + f"1")
        sleep(1)
        print(">> Loop is starting")


        taskobj = loop.create_task(thread1task())
        print(">> starting second thread...")
        _thread.start_new_thread(thread2task,())
        print(">> running loop ...")

        loop.run_forever()
    except KeyboardInterrupt:
        loop.stop()
        _thread.exit() # does not work, code hangs
        print(f"INTERRUPTED")

The hangup is not always at the exact same spot, but the "most" debug output I could receive was:

MPY: soft reboot
>> starting script in ... 3
>> starting script in ... 2
>> starting script in ... 1
>> Loop is starting
>> starting second thread...
>> running loop ...thread 2 started

thread 2 talking ...

After that the serial port is blocked, device does not react to CTRL+C or any other keys.

Executing the code above with V1.21 has no issues and runs forever as expected.

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied