ابزارهای درون‌نگری خط فرمان

کد منبع: Lib/asyncio/tools.py


می‌توان ماژول asyncio را به‌عنوان یک اسکریپت از طریق python -m asyncio فراخوانی کرد تا گراف وظایف (task graph) فرایند پایتون دیگری که در حال اجرا است، بدون تغییر آن یا راه‌اندازی مجدد آن بررسی شود. زیرماژول asyncio.tools این رابط را پیاده‌سازی می‌کند.

دستورات زیر فرایند شناسایی‌شده با PID را بررسی می‌کنند:

$ python -m asyncio pstree PID
$ python -m asyncio ps PID

این دستورات وضعیت فرایند هدف را بدون اجرای هیچ کدی در آن می‌خوانند. آن‌ها فقط روی پلتفرم‌های پشتیبانی‌شده در دسترس هستند و ممکن است برای بازرسی یک فرایند دیگر به مجوز نیاز داشته باشند. برای جزئیات، الزامات مجوز را ببینید.

همچنین ملاحظه نمائید

درون‌نگری گراف فراخوانی

API های برنامه‌ای برای بازرسی گراف فراخوانی ناهمگام یک وظیفه یا آینده‌نما در فرایند جاری.

مثال‌های دستوری زیر از این برنامه استفاده می‌کنند، که یک سلسله‌مراتب وظیفه مناسب برای بازرسی ایجاد می‌کند و شناسه فرآیند خود را چاپ می‌کند:

example.py
import asyncio
import os

async def play(track):
    await asyncio.sleep(3600)
    print(f"🎵 Finished: {track}")

async def album(name, tracks):
    async with asyncio.TaskGroup() as tg:
        for track in tracks:
            tg.create_task(play(track), name=track)

async def main():
    print(f"PID: {os.getpid()}")
    async with asyncio.TaskGroup() as tg:
        tg.create_task(
            album("Sundowning", ["TNDNBTG", "Levitate"]),
            name="Sundowning",
        )
        tg.create_task(
            album("TMBTE", ["DYWTYLM", "Aqua Regia"]),
            name="TMBTE",
        )

asyncio.run(main())

برنامه را در یک پایانه اجرا کنید و بگذارید در حال اجرا بماند:

$ python example.py
PID: 12345

سپس از پایانه‌ای دیگر، شناسه‌ی فرایند چاپ‌شده را به دستورات بدهید. شناسه‌های نخ، شناسه‌های وظیفه، مسیرهای پرونده و شماره‌های خط در اجراها و چیدمان‌های مختلف منبع متفاوت هستند.

اضافه شده در نسخه‌ی 3.14.

گزینه‌های خط فرمان

pstree PID

نمایش روابط وظیفه و هم‌روال به‌صورت یک درخت. هر وظیفه همراه با پشته‌ی کامل هم‌روال خود نمایش داده می‌شود و به‌صورت تودرتو زیر وظیفه‌ای (در صورت وجود) که آن را await می‌کند، قرار می‌گیرد. این زیردستور برای شناسایی سریع این‌که کدام شاخه از سلسله‌مراتب وظایف مسدود شده است و اجرا در کجای پشته‌ی هم‌روال آن مکث کرده است، مفید است:

$ python -m asyncio pstree 12345
└── (T) Task-1
    └──  main example.py:12
        └──  TaskGroup.__aexit__ Lib/asyncio/taskgroups.py:75
            └──  TaskGroup._aexit Lib/asyncio/taskgroups.py:124
                ├── (T) Sundowning
                │   └──  album example.py:7
                │       └──  TaskGroup.__aexit__ Lib/asyncio/taskgroups.py:75
                │           └──  TaskGroup._aexit Lib/asyncio/taskgroups.py:124
                │               ├── (T) TNDNBTG
                │               │   └──  play example.py:4
                │               │       └──  sleep Lib/asyncio/tasks.py:702
                │               └── (T) Levitate
                │                   └──  play example.py:4
                │                       └──  sleep Lib/asyncio/tasks.py:702
                └── (T) TMBTE
                    └──  album example.py:7
                        └──  TaskGroup.__aexit__ Lib/asyncio/taskgroups.py:75
                            └──  TaskGroup._aexit Lib/asyncio/taskgroups.py:124
                                ├── (T) DYWTYLM
                                │   └──  play example.py:4
                                │       └──  sleep Lib/asyncio/tasks.py:702
                                └── (T) Aqua Regia
                                    └──  play example.py:4
                                        └──  sleep Lib/asyncio/tasks.py:702

اگر گراف await شامل یک دور باشد، pstree به‌جای چاپ یک درخت، خطایی را گزارش می‌کند. وجود دور در گراف await غیرمعمول است و معمولاً نشان‌دهنده‌ی یک خطای برنامه‌نویسی است:

$ python -m asyncio pstree 12345
ERROR: await-graph contains cycles - cannot print a tree!

cycle: Task-2 → Task-3 → Task-2
ps PID

نمایش یک جدول تخت از تمام وظایف در انتظار در فرایند PID. هر ردیف شناسه‌ی نخ حلقه‌ی رویداد، شناسه و نام وظیفه، پشته‌ی هم‌روال، و در صورت وجود، پشته، نام و شناسه‌ی وظیفه منتظر را نشان می‌دهد.

این زیردستور همه وظایف را صرف‌نظر از اینکه گراف await حاوی چرخه باشد، چاپ می‌کند:

$ python -m asyncio ps 12345
tid        task id              task name            coroutine stack                                    awaiter chain                                      awaiter name    awaiter id
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
18445801   0x10a456060          Task-1               TaskGroup._aexit -> TaskGroup.__aexit__ -> main                                                                       0x0
18445801   0x10a439f60          Sundowning           TaskGroup._aexit -> TaskGroup.__aexit__ -> album   TaskGroup._aexit -> TaskGroup.__aexit__ -> main    Task-1          0x10a456060
18445801   0x10a439d70          TMBTE                TaskGroup._aexit -> TaskGroup.__aexit__ -> album   TaskGroup._aexit -> TaskGroup.__aexit__ -> main    Task-1          0x10a456060
18445801   0x10a2a3a80          TNDNBTG              sleep -> play                                      TaskGroup._aexit -> TaskGroup.__aexit__ -> album   Sundowning      0x10a439f60
18445801   0x10a2a38a0          Levitate             sleep -> play                                      TaskGroup._aexit -> TaskGroup.__aexit__ -> album   Sundowning      0x10a439f60
18445801   0x10a2d7150          DYWTYLM              sleep -> play                                      TaskGroup._aexit -> TaskGroup.__aexit__ -> album   TMBTE           0x10a439d70
18445801   0x10a6bdaa0          Aqua Regia           sleep -> play                                      TaskGroup._aexit -> TaskGroup.__aexit__ -> album   TMBTE           0x10a439d70