یک فرآیند پسزمینهٔ نشتکرده میتواند کل چرخه توسعه یک عامل هوش مصنوعی را متوقف کند. Corral، یک ابزار تخصصی لینوکس، تضمین میکند که وقتی دستوری متوقف میشود، تکتک فرآیندهای فرزند آن نیز همزمان نابود شوند. وقتی Corral بازمیگردد، هیچ فرآیندی که توسط آن دستور شروع شده باشد، زنده نمیماند؛ Corral پیش از بازگشت، این موضوع را تأیید میکند. اگر ابزار نتواند این پاکسازی را اثبات کند، با کد خروجی ۱۲۰ خارج میشود.
اکثر عاملهای کدنویس هوش مصنوعی و اجراکنندههای CI دستوراتی را در شل اجرا میکنند که خودشان ننوشتهاند. آنها بر اساس یک مدل ناقص عمل میکنند: یک سیگنال به فرآیند فرزند یا گروه پردازشی فرزند میفرستند و سپس منتظر بسته شدن لولههای خروجی (output pipes) میمانند. این روش در سه مورد رایج شکست میخورد:
۱. دیمونیزه شدن (Daemonization): یک دیمون دو بار فورک (fork) میکند و تابع setsid() را فراخوانی میکند. در این حالت، فرآیند در یک گروه پردازشی و نشست (session) متفاوت قرار میگیرد و init به عنوان والد آن شناخته میشود، بنابراین سیگنال هرگز به آن نمیرسد.
۲. تعلیق لوله (Pipe Hanging): یک فرآیند پسزمینه، خروجیهای استاندارد (stdout) یا خطاهای استاندارد (stderr) را باز نگه میدارد. در نتیجه، اجراکننده هرگز علامت پایان فایل (EOF) را نمیخواند و حتی پس از خروج دستور، در حالت تعلیق باقی میماند.
۳. نادیده گرفتن سیگنال: یک فرآیند سیگنال SIGTERM را نادیده میگیرد و به اجرای خود ادامه میدهد.
همانطور که در تحلیلهای پیشین ما دربارهی پایداری زیرساختهای عاملمحور اشاره کردیم، این فرآیندهای «زامبی» باعث اشغال قفل فایلها، پورتها و منابع CPU میشوند و اجرای بعدی عامل را با شکست مواجه میکنند. این چالشها در محیطهای اتوماسیون شدیدتر است؛ برای مثال در استفاده از حالت بدون سر (headless) در Claude Code برای بازبینی کد، مدیریت دقیق فرآیندهای پسزمینه برای جلوگیری از تداخل در تسکهای متوالی حیاتی است. طبق مستندات github.com، Corral این مشکل را با کنترل کامل درخت فرآیند، بهجای تمرکز بر فرزند مستقیم، حل میکند. این ابزار برای تضمین پاکسازی از دو حالت عملیاتی متمایز بهره میبرد:
حالت اجباری (Enforced Mode)
در حالت اجباری، Corral دستور را در یک گروه cgroup v2 اختصاصی قرار میدهد. این قابلیت — که شبیه به یک حصار سختافزاری برای هر برنامه است — به هسته لینوکس اجازه میدهد تمام فرآیندهای فرزند را، فارغ از اینکه چند بار فورک شدهاند یا نشست خود را تغییر دادهاند، ردیابی کند. این رویکرد یادآور راهکار Cognous در انتقال حفاظها به سطح سختافزار است تا از رفتارهای پیشبینینشده عاملهای خودمختار جلوگیری شود. یک نوشتن ساده در فایل cgroup.kill تمام فرآیندهای آن گروه را فوراً متوقف میکند. این حالت نیازمند یک cgroup تفویضشده است؛ اسکریپت ارائه شده در scripts/corral-enforced یکی از این گروهها را با استفاده از systemd-run ایجاد میکند.
این حالت همچنین امکان اعمال محدودیتهای سختگیرانه منابع را فراهم میکند:
- محدودیت حافظه از طریق پرچم
--mem(مثلاً--mem 512M). - محدودیت تعداد فرآیندها از طریق پرچم
--pids(مثلاً--pids 64).
حالت جایگزین (Fallback Mode)
زمانی که cgroups در دسترس نباشند، Corral بهعنوان یک child subreaper عمل میکند. این بدان معناست که هر فرآیند یتیمی بهطور خودکار فرزند Corral میشود. ابزار با اسکن /proc و بررسی والد، گروه پردازشی و نشست، تمام فرآیندهای باقیمانده را مییابد تا زمانی که هیچ فرآیندی باقی نماند. Corral سیگنالها را به فرآیندهایی که فرزند مستقیم آن نیستند، تنها از طریق pidfds و پس از بررسی مجدد فرآیند ارسال میکند تا اطمینان حاصل شود که یک PID بازیافتشده بهطور تصادفی سیگنالی دریافت نمیکند.
پیکربندی و گزینهها
این ابزار بهصورت پیشفرض از --cgroup-mode=auto استفاده میکند که در صورت امکان، حالت اجباری را انتخاب میکند. برخی از گزینههای کلیدی عبارتاند از:
--wall DURATION: تعیین محدودیت زمانی برای اجرا (مثلاً30sیا5m).--grace DURATION: فاصله زمانی بین ارسال سیگنال SIGTERM و SIGKILL (پیشفرض ۲ ثانیه).--verify-timeout DURATION: محدودیت زمانی برای بررسی نهایی پاکسازی (پیشفرض ۲ ثانیه).--max-output SIZE: محدود کردن حجم ترکیبی stdout و stderr (مثلاً1M).--json PATH: ثبت یک رکورد حسابرسی شامل حالت اجرا، محدودیتها، دلیل پایان، زمانبندی مراحل و PIDهای هر فرآیندی که در توقف شکست خورده است.--stdin POLICY: تنظیم سیاست ورودی استاندارد رویnullیاinherit.
عملکرد و بنچمارکها
در تستهای رودررو با ابزارهای استاندارد مانند timeout -k 1s 2s، Corral قابلیت اطمینان برتری از خود نشان داد. با استفاده از bench/compare.py، ده برنامه تست از پوشه faults/ هر کدام پنج بار با محدودیت زمانی ۲ ثانیه اجرا شدند. Corral (در هر دو حالت اجباری و جایگزین) در تکتک موارد تست، صفر فرآیند زنده باقی گذاشت.
در مقابل، سایر اجراکنندهها شکستهای قابلتوجهی داشتند:
- NV (اجراکننده پایتونی): در موارد F3، F4، F5، F7 و F8 دچار تعلیق شد یا فرآیندها را زنده باقی گذاشت.
- TO (timeout): در موارد F5 و F7 (در ۱ مورد از ۵ اجرا) فرآیندها را زنده باقی گذاشت. در مورد F7، جایی که دستور ۲۰۰ فرزند ایجاد کرده بود، اجراکننده پایتونی ۱۹۲ فرآیند را زنده باقی گذاشت.
نتایج خاص نشان داد که حالت اجباری (CE) برنامه F9 را در لحظه رسیدن به محدودیت ۶۴ مگابایت حافظه، تنها در ۰.۱۲ ثانیه متوقف کرد. از نظر سربار، اجرای دستور /bin/true در حالت جایگزین ۶.۶۴ میلیثانیه (P50) و در حالت اجباری ۱۱.۳۳ میلیثانیه (P50) زمان میبرد، در حالی که اجرای مستقیم آن ۰.۸۳ میلیثانیه است. این تستها روی یک سرور ابری Hetzner با ۲ پردازنده مجازی اشتراکی (Intel Xeon, Skylake)، اوبونتو ۲۶.۰۴ و هسته ۷.۰ انجام شده است.
الزامات فنی و نصب
برای استفاده از Corral، به لینوکس ۵.۱۱ یا بالاتر نیاز است و برای حالت اجباری، نسخه ۵.۱۴ الزامی است. باینریهای پیشساخته برای سیستمهای x86-64 با glibc ۲.۳۶ یا بالاتر (سازگار با اوبونتو ۲۲.۱۰، دبیان ۱۲ یا فدورا ۳۷) طراحی شدهاند.
نصب از طریق باینری:curl -LO https://github.com/Cardinal44/corral/releases/latest/download/corral-linux-x86_64.tar.gztar -xzf corral-linux-x86_64.tar.gzsudo cp corral-linux-x86_64/corral corral-linux-x86_64/corral-enforced /usr/local/bin/
ساخت از سورس:
نیازمند glibc ۲.۳۶، CMake 3.22، Ninja و GCC 11 یا Clang 14 است. برای اجرای تستها به پایتون ۳.۱۰ نیاز است.cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Releasecmake --build buildctest --test-dir build --output-on-failure
کدهای خروجی و محدودیتها
Corral از کدهای خروجی خاصی برای گزارش نتیجه استفاده میکند:
- کد دستور: دستور بهطور طبیعی خارج شده است.
- ۱۲۴: زمان محدود شده به پایان رسید.
- ۱۲۱: محدودیت حافظه لمس شد.
- ۱۲۲: محدودیت خروجی لمس شد.
- ۱۲۰: شکست در پاکسازی (Corral نتوانست اثبات کند تمام فرآیندها متوقف شدهاند). این کد بر تمام کدهای دیگر اولویت دارد.
- ۱۲۵: شکست در راهاندازی یا گزینه نادرست.
- ۱۲۶، ۱۲۷: دستور شروع نشد (۱۲۷: یافت نشد).
- ۱۲۸ + N: سیگنال N دستور را متوقف کرد (مثلاً ۱۳۰ برای Ctrl-C).
محدودیتها:
Corral یک Sandbox امنیتی نیست؛ دسترسی به شبکه، فایلها یا امتیازات (privileges) را محدود نمیکند. این ابزار نمیتواند کارهای شروع شده خارج از درخت فرآیند خود (مثلاً از طریق at، D-Bus یا systemd-run) را ببیند. در حالت جایگزین، نمیتواند به فرزندان setuid سیگنال دهد و با کد ۱۲۰ خارج میشود. اگر خودِ Corral با SIGKILL متوقف شود، تنها توقف فرزند مستقیم تضمین میشود. در حال حاضر این ابزار فاقد پشتیبانی از PTY و محدودیتهای زمان CPU است و فقط روی لینوکس اجرا میشود.
برای توسعهدهندگان، این ابزار بار پاکسازی را از دوش پرامپتهای عامل یا منطق اجراکننده به هسته سیستمعامل منتقل میکند. با تضمین یک محیط پاک (clean slate)، یکی از منابع اصلی شکستهای غیرقطعی در گردشکارهای کدنویسی خودکار حذف میشود.
برای توسعهدهندگان، این ابزار بار پاکسازی را از دوش پرامپتهای عامل یا منطق اجراکننده به هسته سیستمعامل منتقل میکند. با تضمین یک محیط پاک (clean slate)، یکی از منابع اصلی شکستهای غیرقطعی در گردشکارهای کدنویسی خودکار حذف میشود.
گام بعدی شما
- اگر از عاملهای کدنویس در محیطهای Docker یا CI استفاده میکنید، Corral را جایگزین
timeoutکنید تا از اشغال منابع سرور جلوگیری شود. - برای محیطهای حساس، از حالت Enforced و پرچم
--memاستفاده کنید تا از مصرف بیرویه رم توسط مدلهای کدنویس جلوگیری کنید. - خروجی JSON ابزار را به سیستم مانیتورینگ خود متصل کنید تا متوجه شوید کدام دستورات عامل شما تمایل به ایجاد فرآیندهای زامبی دارند.
اما مدیریت منابع تنها بخشی از چالش است؛ برای درک نحوه بهینهسازی هزینه استنتاج در مقیاس بالا، تحلیل ما درباره تراشههای Blackwell را بخوانید.




گفتگو