"RuntimeError: Racing with another loop to spawn a process" when spawning many processes from multiple threads
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Anfängerfreundlichkeit
- 35/100
- Issue-Typ
- Bug
- Klarheit
- Größtenteils klar
- Aktivitätsstatus
- Veraltet
- Tech-Stack
- python
- Bereich
- backend, operating-systems
Rechercherichtung
Beginne mit dem minimalen Reproducer rund um asyncio.create_subprocess_exec, asyncio.run und uvloop.install und vergleiche sein Verhalten mit vanilla asyncio unter PYTHONASYNCIODEBUG. Verfolge den Pfad zum Starten von Subprozessen, der von konkurrierenden Event-Loops verwendet wird; fertig ist die Aufgabe, wenn der Reproducer mit Threads alle Prozesse starten und auf sie warten kann, ohne dass der durch den Race verursachte RuntimeError auftritt.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
- uvloop version:
0.17.0 - Python version:
3.10.8 - Platform: Arch Linux
- Can you reproduce the bug with
PYTHONASYNCIODEBUGin env?: Yes - Does uvloop behave differently from vanilla asyncio? How?: Yes, there is no exception.
We have a multi-threaded application using uvloop that sometimes needs to spawn a lot of processes simultaneously.
This results in a lot of "RuntimeError: Racing with another loop to spawn a process" exceptions being raised.
The following is a minimal reproducible example that shows the problem:
import asyncio
from threading import Thread
import uvloop
def create_processes(i):
async def inner():
processes = []
for _ in range(100):
p = await asyncio.create_subprocess_exec("true")
processes.append(p)
for p in processes:
await p.wait()
try:
asyncio.run(inner())
print(f"[{i}] Success.")
except Exception as e:
print(f"[{i}] Fail: {repr(e)}")
def main():
threads = []
for i in range(10):
t = Thread(target=lambda: create_processes(i))
t.start()
threads.append(t)
for t in threads:
t.join()
uvloop.install()
main()
When running this with PYTHONASYNCIODEBUG=1 I get something like:
Executing <Task pending name='Task-3' coro=<create_processes.<locals>.inner() running at /home/tyilo/repos/uvloop-race/test.py:11> wait_for=<Future pending cb=[Task.task_wakeup()] created at /usr/lib/python3.10/asyncio/subprocess.py:218> cb=[run_until_complete.<locals>.done_cb()] created at /usr/lib/python3.10/asyncio/tasks.py:636> took 0.132 seconds
Executing <Handle UVProcessTransport._call_connection_made created at /usr/lib/python3.10/asyncio/subprocess.py:218> took 0.133 seconds
Executing <Task pending name='Task-4' coro=<create_processes.<locals>.inner() running at /home/tyilo/repos/uvloop-race/test.py:11> wait_for=<Future pending cb=[Task.task_wakeup()] created at /usr/lib/python3.10/asyncio/subprocess.py:218> cb=[run_until_complete.<locals>.done_cb()] created at /usr/lib/python3.10/asyncio/tasks.py:636> took 0.142 seconds
Executing <Task pending name='Task-6' coro=<create_processes.<locals>.inner() running at /home/tyilo/repos/uvloop-race/test.py:11> wait_for=<Future pending cb=[Task.task_wakeup()] created at /usr/lib/python3.10/asyncio/subprocess.py:218> cb=[run_until_complete.<locals>.done_cb()] created at /usr/lib/python3.10/asyncio/tasks.py:636> took 0.147 seconds
[0] Fail: RuntimeError('Racing with another loop to spawn a process.')
Executing <Task pending name='Task-9' coro=<create_processes.<locals>.inner() running at /home/tyilo/repos/uvloop-race/test.py:11> wait_for=<Future pending cb=[Task.task_wakeup()] created at /usr/lib/python3.10/asyncio/subprocess.py:218> cb=[run_until_complete.<locals>.done_cb()] created at /usr/lib/python3.10/asyncio/tasks.py:636> took 0.157 seconds
Executing <Task pending name='Task-8' coro=<create_processes.<locals>.inner() running at /home/tyilo/repos/uvloop-race/test.py:11> wait_for=<Future pending cb=[Task.task_wakeup()] created at /usr/lib/python3.10/asyncio/subprocess.py:218> cb=[run_until_complete.<locals>.done_cb()] created at /usr/lib/python3.10/asyncio/tasks.py:636> took 0.175 seconds
Executing <Task pending name='Task-7' coro=<create_processes.<locals>.inner() running at /home/tyilo/repos/uvloop-race/test.py:11> wait_for=<Future pending cb=[Task.task_wakeup()] created at /usr/lib/python3.10/asyncio/subprocess.py:218> cb=[run_until_complete.<locals>.done_cb()] created at /usr/lib/python3.10/asyncio/tasks.py:636> took 0.176 seconds
[2] Fail: RuntimeError('Racing with another loop to spawn a process.')
[9] Fail: RuntimeError('Racing with another loop to spawn a process.')
[1] Fail: RuntimeError('Racing with another loop to spawn a process.')
[4] Fail: RuntimeError('Racing with another loop to spawn a process.')
[3] Success.
[6] Success.
[8] Success.
[5] Success.
[7] Success.
Without uvloop I get something like:
[3] Success.
[9] Success.
[5] Success.
[7] Success.
[2] Success.
[4] Success.
[8] Success.
[0] Success.
[6] Success.
[1] Success.
- Vorherrschende Sprache
- Cython
- Sterne
- 11.9k
- Forks
- 615
- PR-Merge-Kennzahlen
- Keine gemergten PRs in 30 T.
Beitragsleitfaden
Für dieses Repository ist kein Beitragsleitfaden indexiert
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus MagicStack/uvloop
-
License not clear Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 68/100
MagicStack/uvloop#759 ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 68/100
MagicStack/uvloop#741 · 2 Reaktionen ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 68/100
MagicStack/uvloop#702 · 8 Kommentare · 9 Reaktionen ·
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 25/100
MagicStack/uvloop#766 ·
-
Directly constructed subprocess pipe protocols segfault when callbacks use a non-process owner Offen
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 52/100
MagicStack/uvloop#765 ·
Alle Issues in MagicStack/uvloop
Ähnliche Issues
-
enhancement
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 70/100
canonical/paas-charm#368 · 1 Kommentar ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
-
tech debt
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
-
area:workflow bug ready-for-agent
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
fil-donadoni/tolaria#4409 ·
-
status/awaiting_triage
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100