رفتن به محتوا
مبانی کامپیوتر و اینترنتکامپیوتر از دروندرس ۷ از ۱۶

سیستم‌عامل و برنامه‌های در حال اجرا

سیستم‌عامل چه می‌کند (پروسه‌ها، حافظه، فایل، دستگاه‌ها، کاربر و دسترسی)، فرق برنامه و پروسه، دیدن پروسه‌ها با ps و top، تقسیم پردازنده بین چند پروسه (هشت برنامه روی چهار هسته)، کاربر و دسترسی (Permission denied)، خواندن load average با uptime، و پشت پرده: فراخوانی سیستمی (system call) با strace.

  • حدود ۲۱ دقیقه مطالعه
  • ۷ مثال اجراشده
  • ۳ تمرین با جواب
  • مقدماتی (از صفر مطلق)
  • به‌روزرسانی: ۲۹ مهر ۱۴۰۵

توی این درس یاد می‌گیری سیستم‌عامل دقیقاً چه کاری می‌کند و چرا بدون آن هر برنامه باید خودش با دیسک و پردازنده و صفحه‌کلید سروکله بزند. فرق برنامه (program) و پروسه (process) را می‌فهمی، پروسه‌های واقعی را با ps و top می‌بینی، آزمایش می‌کنی که هشت برنامه چطور روی چهار هسته با هم اجرا می‌شوند، می‌بینی چرا گاهی می‌گوید Permission denied، و در بخش «پشت پرده» با ابزار strace می‌بینی یک برنامه‌ی ساده چطور از سیستم‌عامل کمک می‌خواهد.

همین الان روی کامپیوتر تو شاید یک مرورگر باز است، یک آهنگ پخش می‌شود و یک فایل دانلود می‌شود. پردازنده‌ی تو شاید چهار هسته دارد؛ پس چطور ده‌ها برنامه «همزمان» کار می‌کنند؟ و چرا یک برنامه‌ی خراب نمی‌تواند کل کامپیوتر را بخواباند (معمولاً)؟ و چرا برنامه‌ی من نمی‌تواند فایل‌های تو را بخواند؟ جواب هر سه سؤال یکی است: سیستم‌عامل.

تشبیه: مدیر آشپزخانه و دستور پخت

Section titled “تشبیه: مدیر آشپزخانه و دستور پخت”

در درس اول سیستم‌عامل را «مدیر آشپزخانه» نامیدیم. حالا دقیق‌تر: یک برنامه مثل دستور پخت روی کاغذ است: ثابت، روی دیسک. وقتی آشپز آن را درحال پختن می‌گذارد، یک غذای در حال پخت داریم: این همان پروسه است، با وضعیت (چه مرحله‌ای؟)، مواد روی میز (RAM) و یک شماره‌ی سفارش.

  • یک دستور پخت را می‌شود همزمان دو بار پخت: یک برنامه، دو پروسه با دو شماره‌ی سفارش.
  • مدیر آشپزخانه تصمیم می‌گیرد کدام غذا نوبت آشپز دارد: چند میلی‌ثانیه به یکی، بعد دیگری، دوباره اولی… آن‌قدر سریع که از بیرون همه «همزمان» پخته می‌شوند.
  • هیچ آشپزی حق ندارد مستقیم به انبار برود یا میز آشپز دیگر را بردارد؛ باید از مدیر بخواهد.

سیستم‌عامل چه می‌کند؟

Section titled “سیستم‌عامل چه می‌کند؟”
کار یعنی چه مثال
مدیریت پروسه‌ها پردازنده را بین پروسه‌ها تقسیم می‌کند و هر کدام را شروع یا متوقف می‌کند هشت برنامه روی چهار هسته
مدیریت حافظه به هر پروسه RAM می‌دهد و نمی‌گذارد به RAM دیگری دست بزند خراب شدن یک برنامه بقیه را خراب نمی‌کند
مدیریت فایل فایل‌ها و پوشه‌ها روی دیسک (درس قبل) index.html در css/
مدیریت دستگاه‌ها با کمک «درایور» با صفحه‌کلید، چاپگر، کارت شبکه حرف می‌زند یک برنامه با هر ماوسی کار می‌کند
کاربر و دسترسی مشخص می‌کند هر کاربر به چه چیزی دست بزند Permission denied
شبکه ارتباط با کامپیوترهای دیگر را فراهم می‌کند وب (درس‌های بعد)

هسته (kernel) قلب سیستم‌عامل است و این کارها را انجام می‌دهد. «سیستم‌عامل» معمولاً یعنی هسته به‌علاوه‌ی ابزارها و محیط‌های کار کاربر (پنجره‌ها، ترمینال، دستورها). چند نمونه: Windows (هسته‌ی NT)، macOS (هسته‌ی XNU)، لینوکس (هسته‌ی Linux) و Android (که روی هسته‌ی Linux ساخته شده). همین‌طور که در دوره‌ی «لینوکس از صفر» می‌بینی، بیشتر سرورهای دنیا لینوکسی‌اند.

وقتی کامپیوتر روشن می‌شود، یک برنامه‌ی کوچک در سخت‌افزار (firmware) اجرا می‌شود، بعد برنامه‌ای که هسته را پیدا و در RAM می‌گذارد (bootloader). هسته که بالا آمد، اولین پروسه را می‌سازد (شماره‌ی ۱) و آن بقیه‌ی سرویس‌ها و صفحه‌ی ورود را راه می‌اندازد.

دستورهای این درس روی یک کامپیوتر لینوکسی (Ubuntu) اجرا شده‌اند و فعلاً فقط ببین و بخوان؛ لازم نیست چیزی را تایپ کنی یا ساختار دستورها را بفهمی. در دوره‌ی لینوکس اول یک Ubuntu روی کامپیوتر خودت راه می‌اندازی و همه‌ی این‌ها را خودت امتحان می‌کنی. اگر ویندوز داری، معادل همه‌ی این‌ها در Task Manager (کلید Ctrl+Shift+Esc) هست، و روی مک در Activity Monitor.

مثال ۱: من کیستم و این چه سیستمی است؟

Section titled “مثال ۱: من کیستم و این چه سیستمی است؟”
Terminal window
whoami
id
hostname
uname -r
head -2 /etc/os-release
خروجی
ali
uid=1001(ali) gid=1001(ali) groups=1001(ali)
pc
6.8.0-85-generic
PRETTY_NAME="Ubuntu 24.04.5 LTS"
NAME="Ubuntu"
  • whoami: کاربر فعلی ali است.
  • id: شماره‌ی کاربر (uid=1001) و گروه‌هایش. سیستم‌عامل کاربر را با شماره می‌شناسد و اسم فقط برای آدم‌هاست.
  • hostname: اسم این ماشین در شبکه (pc).
  • uname -r: نسخه‌ی هسته (kernel). (چیزی شبیه 6.x و بسته به ماشین فرق می‌کند.)
  • /etc/os-release: اسم توزیع: Ubuntu. یعنی بالای این هسته‌ی لینوکس، توزیع Ubuntu نشسته (درس «لینوکس چیست؟»).

مثال ۲: چند وقت است روشن است، و چقدر مشغول است؟ (uptime)

Section titled “مثال ۲: چند وقت است روشن است، و چقدر مشغول است؟ (uptime)”
Terminal window
uptime
nproc
cat /proc/loadavg
خروجی
14:03:10 up 21 min, 1 user, load average: 0.80, 0.34, 0.17
4
0.80 0.34 0.17 1/199 5094
  • uptime: ساعت فعلی، مدت روشن بودن (up 21 min)، تعداد کاربران وارد‌شده، و سه عدد load average: میانگین ۱ دقیقه، ۵ دقیقه و ۱۵ دقیقه‌ی اخیر.
  • nproc: ۴ هسته. load average یعنی «میانگین تعداد پروسه‌هایی که یا الان روی هسته اجرا می‌شوند یا منتظر نوبت‌اند». با ۴ هسته، عدد ۴٫۰ یعنی همه‌ی هسته‌ها پُرند؛ عدد بالاتر یعنی صف. اینجا ۰٫۲ است: تقریباً بیکار.
  • /proc/loadavg منبع همین عددهاست. پوشه‌ی /proc یک «فایل‌سیستم مجازی» است: فایل واقعی روی دیسک نیست و هسته هنگام خواندن آن را همان لحظه می‌سازد. (در دوره‌ی لینوکس بیشتر می‌بینی.)

مثال ۳: چه چیزی در حال اجراست؟ (ps)

Section titled “مثال ۳: چه چیزی در حال اجراست؟ (ps)”

دستور ps (process status) پروسه‌ها را فهرست می‌کند. -e یعنی «همه» و -o ستون‌ها را مشخص می‌کند: شماره‌ی پروسه (PID)، شماره‌ی پروسه‌ی پدر (PPID)، صاحب (USER)، درصد و مقدار RAM (RSS به کیلوبایت) و اسم. --sort=-rss یعنی «از پرمصرف‌ترین به کم‌مصرف‌ترین»:

Terminal window
ps -eo pid,ppid,user,%mem,rss,comm --sort=-rss | head -n 6
خروجی
PID PPID USER %MEM RSS COMMAND
642 1 root 0.6 25344 snapd
351 1 root 0.4 17920 systemd-journal
557 1 root 0.4 16896 multipathd
1 0 root 0.3 13184 systemd
5078 5070 ali 0.1 5364 bash

هر ردیف یک پروسه است (head -n 6 فقط پنج تای اول را نگه داشت؛ کل فهرست حدود ۱۰۰ پروسه است). چند نکته:

  • بیشترشان مال کاربر root (مدیر سیستم) و سرویس‌هایی‌اند که سیستم‌عامل خودش اجرا کرده، مثل systemd-journal که لاگ‌ها را نگه می‌دارد.
  • PPID شماره‌ی پروسه‌ی پدر است: پدر سرویس‌ها پروسه‌ی ۱ است.
  • پروسه‌ی ۱ (systemd) اولین پروسه‌ای است که بعد از روشن شدن کامپیوتر اجرا می‌شود و بقیه را راه می‌اندازد.
  • RSS مقدار RAM واقعی (به کیلوبایت): bash (همان پنجره‌ی دستوری ما) حدود ۵ مگابایت.

مثال ۴: یک برنامه، دو پروسه

Section titled “مثال ۴: یک برنامه، دو پروسه”

برنامه‌ی sleep (فقط چند ثانیه صبر می‌کند) را دو بار پشت‌سرهم، با علامت & (یعنی «در پس‌زمینه اجرا کن و ترمینال را آزاد بگذار») اجرا می‌کنیم:

Terminal window
sleep 300 &
sleep 300 &
sleep 0.3
ps -C sleep -o pid,ppid,user,rss,comm
pkill -u ali sleep
خروجی
PID PPID USER RSS COMMAND
5097 5078 ali 1968 sleep
5098 5078 ali 2020 sleep

دو پروسه‌ی sleep با دو شماره‌ی متفاوت ساخته شد، هر دو فرزند همان bash (PID ۵۰۷۸). برنامه‌ی sleep یکی است و روی دیسک است؛ پروسه‌ها دو تا. هر کدام RAM جدا (حدود ۲ مگابایت) دارند. آخر هم با pkill -u ali sleep فقط sleep ‌های خودمان را بستیم.

مثال ۵: هشت برنامه، چهار هسته

Section titled “مثال ۵: هشت برنامه، چهار هسته”

حالا ببینیم سیستم‌عامل با تقسیم پردازنده چه می‌کند. برنامه‌ی yes بی‌وقفه حرف y چاپ می‌کند (ما خروجی‌اش را دور می‌ریزیم)، پس هر نسخه‌اش یک هسته را کامل مشغول می‌کند. اول هشت نسخه را اجرا می‌کنیم (روی ماشینی که چهار هسته دارد) و بعد با top نگاه می‌کنیم. top -b -n 1 یک عکس از وضعیت می‌گیرد (batch mode، یک بار) و -o %CPU بر اساس مصرف پردازنده مرتب می‌کند:

Terminal window
for i in 1 2 3 4 5 6 7 8; do yes > /dev/null & done
sleep 3
echo "cores: $(nproc)"
top -b -n 1 -o %CPU | sed -n '2,3p;7,15p'
pkill -u ali yes
خروجی
cores: 4
Tasks: 13 total, 9 running, 4 sleeping, 0 stopped, 0 zombie
%Cpu(s): 37.5 us, 62.5 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
5104 ali 20 0 3136 1860 1744 R 54.5 0.0 0:01.65 yes
5102 ali 20 0 3136 1856 1740 R 45.5 0.0 0:01.60 yes
5103 ali 20 0 3136 1848 1732 R 45.5 0.0 0:01.59 yes
5105 ali 20 0 3136 1972 1860 R 45.5 0.0 0:01.57 yes
5106 ali 20 0 3136 1856 1740 R 45.5 0.0 0:01.56 yes
5107 ali 20 0 3136 1912 1792 R 45.5 0.0 0:01.56 yes
5108 ali 20 0 3136 1856 1740 R 45.5 0.0 0:01.60 yes
5109 ali 20 0 3136 1888 1772 R 45.5 0.0 0:01.59 yes

با ۸ پروسه‌ی yes روی ۴ هسته:

  • هر ردیف yes حدود ۴۵ تا ۵۵ درصد از یک هسته می‌گیرد، نه ۱۰۰٪؛ چون هشت نفر چهار صندلی را نوبتی استفاده می‌کنند.
  • جمع ستون %CPU نزدیک ۴۰۰٪ است، یعنی هر چهار هسته کاملاً پُر است. (عددها در هر اجرا کمی فرق می‌کنند؛ با دقت‌های مختلف نمونه‌برداری.)
  • در بالای خروجی: 9 running یعنی هشت yes و خود top همه آماده‌ی اجرایند.
  • ستون %Cpu(s): درصد کل ماشین؛ us وقت صرف‌شده در برنامه‌ها (user)، sy در هسته (system) و id بیکاری (idle)؛ بیکاری صفر است.

این همان «تقسیم زمان» است که در بخش پشت پرده توضیح می‌دهیم.

مثال ۶: چه کسی اجازه‌ی چه کاری دارد؟

Section titled “مثال ۶: چه کسی اجازه‌ی چه کاری دارد؟”

هر پروسه‌ای به‌نام یک کاربر اجرا می‌شود و فقط به چیزهایی دسترسی دارد که آن کاربر اجازه دارد. فایلی که رمزهای سیستم در آن است (/etc/shadow) فقط برای مدیر خوانا است:

Terminal window
id -un
cat /etc/shadow
echo "exit code: $?"
خروجی
ali
cat: /etc/shadow: Permission denied
exit code: 1

cat پروسه‌ای است که به نام کاربر ali اجرا می‌شود. هسته قبل از باز کردن /etc/shadow دسترسی را چک کرد و رد کرد: Permission denied، با کد خروج ۱ (کد ۰ یعنی موفق). این همان سازوکاری است که نمی‌گذارد برنامه‌ی من رمز تو را بخواند. در دوره‌ی لینوکس درس «دسترسی‌ها» دقیق‌تر آن را می‌بینی.

مثال ۷: برنامه‌ها از سیستم‌عامل کمک می‌خواهند (strace)

Section titled “مثال ۷: برنامه‌ها از سیستم‌عامل کمک می‌خواهند (strace)”

یک برنامه‌ی ساده مثل cat که فقط یک فایل را چاپ می‌کند، خودش به دیسک دست نمی‌زند. با strace می‌بینیم چه چیزهایی از سیستم‌عامل خواسته است. -e trace=openat فقط درخواست‌های «باز کردن فایل» را نشان می‌دهد. (LC_ALL=C تنظیم زبان را ساده می‌کند تا ده‌ها خط باز کردن فایل‌های زبان در خروجی نیاید.)

Terminal window
LC_ALL=C strace -e trace=openat cat /etc/hostname 2>&1
خروجی
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/etc/hostname", O_RDONLY) = 3
pc
+++ exited with 0 +++

cat برای نمایش یک فایل سه فایل را از هسته خواست: ۱) /etc/ld.so.cache (فهرست کتابخانه‌ها)، ۲) libc.so.6 (کتابخانه‌ی اصلی که همه‌ی برنامه‌ها استفاده می‌کنند) و ۳) فایل خود ما /etc/hostname. هسته هر بار یک شماره‌ی فایل (= 3) برگرداند، همان شماره‌ای که برنامه برای خواندن استفاده می‌کند. (اگر فایل نبود، به‌جای شماره -1 ENOENT می‌دید، یعنی «چنین فایلی نیست».) خود cat کار سنگینی نمی‌کند؛ کار سخت (پیدا کردن فایل روی دیسک، خواندن بایت‌ها) را سیستم‌عامل انجام می‌دهد.

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

Section titled “پشت پرده: فراخوانی سیستمی و بازه‌های زمانی”

فراخوانی سیستمی (system call). برنامه‌ها اجازه ندارند مستقیم با سخت‌افزار کار کنند؛ پردازنده دو «حالت» دارد: حالت کاربر (برنامه‌های معمولی، با محدودیت) و حالت هسته (فقط سیستم‌عامل، بدون محدودیت). هر وقت برنامه چیزی نیاز دارد (خواندن فایل، چاپ، شبکه)، از سیستم‌عامل درخواست رسمی می‌دهد؛ به این درخواست system call می‌گویند. در مثال ۷ دیدی cat فقط سه فایل را باز کرد (کش کتابخانه‌ها، کتابخانه‌ی C و فایل ما) و همه را از سیستم‌عامل خواست.

برنامه مستقیم با دیسک حرف نمی‌زند. system call «openat» را به هسته می‌دهد؛ هسته دیسک را می‌خواند و یک شماره‌ی فایل (file descriptor) به برنامه برمی‌گرداند.

تقسیم زمان. وقتی از هسته‌ی پردازنده بیشتر پروسه داریم (مثال ۵)، سیستم‌عامل به هر پروسه یک برش زمانی (time slice) کوتاه می‌دهد (چند میلی‌ثانیه)، بعد آن را متوقف و پروسه‌ی بعدی را اجرا می‌کند. به این کار context switch می‌گویند. چون سرعتش زیاد است، از بیرون «همه‌چیز همزمان» دیده می‌شود. اگر پروسه‌ها از هسته‌ها کمتر باشند، هر کدام یک هسته‌ی کامل دارند.

درخت پروسه‌ها. هر پروسه یک پدر دارد. پروسه‌ی شماره‌ی ۱ جد همه است و هسته آن را در پایان boot می‌سازد. وقتی در ترمینال برنامه‌ای اجرا می‌کنی، پدرش همان shell (برنامه‌ی ترمینال) است. اگر پدر بمیرد، فرزندانش به پروسه‌ی ۱ می‌چسبند.

۱) بستن پروسه‌ی کس دیگر

Section titled “۱) بستن پروسه‌ی کس دیگر”
Terminal window
pkill sleep
echo "exit code: $?"
خروجی
pkill: killing pid 7 failed: Operation not permitted
exit code: 1

پروسه‌ی ۷ مال کاربر دیگری (root) است، پس هسته اجازه نمی‌دهد ببندیمش: Operation not permitted. این یک محافظت است: کاربر معمولی نباید بتواند سرویس‌های سیستم را بکشد. دقت کن pkill sleep هر پروسه‌ای با اسم sleep را هدف می‌گیرد، حتی مال کس دیگر؛ پس بهتر است همیشه صاحب را مشخص کنی (pkill -u ali sleep).

۲) بستن پروسه‌ای که وجود ندارد

Section titled “۲) بستن پروسه‌ای که وجود ندارد”
Terminal window
kill 99999
خروجی
bash: kill: (99999) - No such process

شماره‌ی ۹۹۹۹۹ پروسه‌ای ندارد. پیش از kill، شماره را با ps یا pgrep دوباره چک کن؛ شماره‌ها بعد از بسته شدن پروسه به پروسه‌ی دیگری داده می‌شود و بستن شماره‌ی کهنه ممکن است پروسه‌ی بی‌ربط را ببندد.

۳) قاطی کردن برنامه و پروسه

Section titled “۳) قاطی کردن برنامه و پروسه”

«برنامه را بستم ولی هنوز در لیست است!» معمولاً یعنی پنجره را بسته‌ای ولی پروسه هنوز زنده است (یا برنامه چند پروسه دارد). برای اطمینان، پروسه را با ps یا pgrep جستجو کن، نه فقط پنجره را نگاه کن.

۴) نگران شدن از load average بالا بدون نگاه به تعداد هسته

Section titled “۴) نگران شدن از load average بالا بدون نگاه به تعداد هسته”

load average ۴٫۰ روی ماشین چهارهسته‌ای یعنی «همه‌ی هسته‌ها پُر، ولی هیچ پروسه‌ای در صف نیست»؛ روی ماشین تک‌هسته‌ای یعنی «چهار برابر ظرفیت!». همیشه با nproc مقایسه کن.

تمرینآسان

یک پروسه‌ی sleep 200 در پس‌زمینه شروع کن، شماره‌ی PID اش را از $! بگیر، با ps اطلاعاتش را ببین و بعد با kill ببندش. ثابت کن بسته شده.

دیدن جواب
Terminal window
sleep 200 &
pid=$!
echo "started PID $pid"
ps -p "$pid" -o pid,ppid,stat,rss,comm
kill "$pid"
sleep 0.3
ps -p "$pid" -o pid,comm || echo "PID $pid is gone"
خروجی
started PID 5122
PID PPID STAT RSS COMMAND
5122 5078 S 2040 sleep
PID COMMAND
PID 5122 is gone

$! شماره‌ی آخرین پروسه‌ی پس‌زمینه است. بعد از kill (که مؤدبانه از پروسه می‌خواهد تمام کند)، ps دیگر چیزی پیدا نکرد (کد خروج ۱) و ما پیام «gone» را چاپ کردیم.

تمرینمتوسط

نشان بده روی ماشین تو چند هسته داریم، و با اجرای ۲ پروسه‌ی پرمصرف (yes) نشان بده مجموع مصرف CPU حدود ۲۰۰٪ می‌شود (هر هسته ۱۰۰٪). از top -b -n 1 استفاده کن و مجموع ستون %CPU را با awk بشمار.

دیدن جواب
Terminal window
echo "cores: $(nproc)"
yes > /dev/null & yes > /dev/null &
sleep 3
top -b -n 1 -o %CPU | awk '/^ *PID/ {go=1; next} go && $NF=="yes" {s += $9; n++} END {print n " yes processes use " s "% CPU in total"}'
pkill -u ali yes
خروجی
cores: 4
2 yes processes use 190.9% CPU in total

دو پروسه‌ی yes روی هم ۱۹۰٪ CPU مصرف کردند، یعنی تقریباً دو هسته‌ی کامل از چهار هسته (یکی چیزی کمتر از ۱۰۰٪ می‌گیرد چون خود top و سیستم هم کمی وقت می‌خواهند). در awk: خط سرستون (PID) را پیدا می‌کنیم، و از بعد آن برای هر خطی که آخرین ستونش yes است، ستون نهم (%CPU) را جمع می‌زنیم.

تمرینسخت

تمرین اصلی درس: یک اسکریپت بنویس که پرمصرف‌ترین پروسه‌ی کاربر فعلی را پیدا کند، اسم و درصد CPU اش را چاپ کند، و اگر از یک آستانه (مثلاً ۸۰٪) بیشتر بود آن را ببندد. با یک حلقه‌ی بی‌پایان (yes) آزمایشش کن، همان سناریوی ابتدای درس.

دیدن جواب
watchdog.sh
#!/usr/bin/env bash
# kills the top CPU process of the current user if it uses more than LIMIT percent
limit=${1:-80}
read -r pid cpu name < <(ps -u "$(id -u)" -o pid=,%cpu=,comm= --sort=-%cpu | head -n 1)
echo "top process: $name (PID $pid) uses $cpu% CPU"
if awk -v c="$cpu" -v l="$limit" 'BEGIN {exit !(c > l)}'; then
kill "$pid" && echo "over $limit%: killed PID $pid"
else
echo "under $limit%: left alone"
fi
Terminal window
echo "--- quiet system:"
bash watchdog.sh 80
echo "--- with a runaway process:"
yes > /dev/null &
sleep 2
bash watchdog.sh 80
sleep 0.3
pgrep -u ali yes || echo "yes is gone"
rm -f watchdog.sh
خروجی
--- quiet system:
top process: bash (PID 5078) uses 0.5% CPU
under 80%: left alone
--- with a runaway process:
top process: yes (PID 5142) uses 99.0% CPU
over 80%: killed PID 5142
yes is gone

اسکریپت از ps -u کاربر --sort=-%cpu پرمصرف‌ترین را برداشت. با سیستم ساکت پرمصرف‌ترین bash خود ما با ۰٫۵٪ بود: «دست نمی‌زنیم». وقتی yes را در حلقه انداختیم، ۹۹٪ شد و اسکریپت آن را kill کرد. دو نکته‌ی فنی: ۱) awk برای مقایسه‌ی عدد اعشاری لازم است (در bash خالی -gt فقط عدد صحیح می‌فهمد). ۲) ستون %cpu در ps میانگین مصرف از شروع پروسه است (برخلاف top که لحظه‌ای نشان می‌دهد)؛ برای همین دو ثانیه صبر کردیم تا yes آن‌قدر وقت داشته باشد که میانگینش بالا برود. اسکریپت واقعی‌تر برای پایش باید چند بار نمونه بگیرد.

⚡ بررسی سریع

یک دستور پخت دو بار هم‌زمان پخته می‌شود. در دنیای کامپیوتر این چیست؟

آزمونک
  1. سیستم‌عامل با هشت پروسه‌ی پرمصرف روی ماشین چهارهسته‌ای چه می‌کند؟

  2. مدیر سرور در top پروسه‌ای را می‌بیند که ۱۰۰٪ CPU می‌خورد. اول چه چیزی را بررسی می‌کند؟

  3. کاربر معمولی دستور cat /etc/shadow را می‌زند و Permission denied می‌گیرد. چرا؟

  4. system call چیست؟

  5. روی ماشین چهارهسته‌ای load average برابر ۴٫۰ است. یعنی چه؟

  • سیستم‌عامل بین برنامه‌ها و سخت‌افزار واسطه است: پروسه، حافظه، فایل، دستگاه‌ها، کاربر و دسترسی، شبکه. قلبش هسته است (Windows، macOS و لینوکس هر کدام هسته‌ی خود را دارند).
  • برنامه دستور پخت روی دیسک است؛ پروسه نسخه‌ی در حال اجرا با PID، RAM و صاحب. یک برنامه می‌تواند چند پروسه شود.
  • با ps و top (در ویندوز Task Manager) پروسه‌ها را می‌بینی؛ kill PID یک پروسه‌ی خودت را می‌بندد.
  • سیستم‌عامل پردازنده را به برش‌های چند میلی‌ثانیه‌ای تقسیم می‌کند؛ هشت پروسه روی چهار هسته نوبتی اجرا می‌شوند و مجموع ‎CPU‎ حدود ۴۰۰٪ است.
  • هر پروسه با هویت یک کاربر اجرا می‌شود و فقط به چیزهایی دسترسی دارد که آن کاربر مجاز است (Permission denied).
  • برنامه‌ها برای هر کار حساس system call می‌زنند؛ strace آن‌ها را نشان می‌دهد.
  • load average را همیشه با nproc مقایسه کن.
برگه‌ی تقلب این درس
دستورکاری که می‌کند
whoamiکاربر فعلی
idشماره و گروه‌های کاربر
uname -rنسخه‌ی هسته
uptimeمدت روشن بودن و load average
ps -eo pid,ppid,user,%mem,rss,commفهرست پروسه‌ها با ستون دلخواه
top -b -n 1 -o %CPUعکس از وضعیت، مرتب بر اساس CPU
sleep 300 &اجرای برنامه در پس‌زمینه
pgrep -u ali sleepپیدا کردن PID بر اساس اسم
kill PIDبستن پروسه
pkill -u ali yesبستن همه‌ی پروسه‌های خودت با این اسم
strace -e trace=openat cmdدیدن فایل‌هایی که برنامه باز می‌کند