Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

"RuntimeError: Racing with another loop to spawn a process" when spawning many processes from multiple threads

オープン
#508 コメント 2 件 リアクション 2 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
35/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
停滞
技術スタック
python

調査の方向性

asyncio.create_subprocess_exec、asyncio.run、uvloop.install を使った最小の再現コードから始め、PYTHONASYNCIODEBUG 下での vanilla asyncio と動作を比較します。並行するイベントループが使用するサブプロセス起動経路を追跡します。スレッドを使った再現コードですべてのプロセスを起動して待機でき、競合による RuntimeError が発生しなければ完了です。

索引モデルが issue の本文から書いたものです。

説明

  • uvloop version: 0.17.0
  • Python version: 3.10.8
  • Platform: Arch Linux
  • Can you reproduce the bug with PYTHONASYNCIODEBUG in 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.
主要言語
Cython
スター
11.9k
フォーク
615
PR マージ指標
30日以内にマージされた PR はありません

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

MagicStack/uvloop のほかの issue

MagicStack/uvloop の issue をすべて見る

似ている issue

Backend & API Design の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。