فصل ششم - پروسس‌ها

از Linuxreview Wiki
پرش به: ناوبری, جستجو


مقدمه
شما در این فصل مفهوم process و job در یک سیستم یونیکسی را خواهید آموخت. در یونیکس هر برنامه‌ای به عنوان یک process اجرا میشود. همچنین در این فصل به تعریف اصطلاحات foreground و background پرداخته شده و چگونی شروع یک process شرح داده میشود، در ادامه نحوه‌ی kill کردن processها و در نهایت مفهوم والد و فرزند برای یک process توضیح داده شده است.


محتویات

شروع یک process

شما در فصل‌های قبل با برخی از دستورات یونیکس آشنا شدید. هر زمان که شما یک دستور را اجرا میکنید در واقع در حال شروع کردن یک process هستید. به عنوان مثال وقتی شما دستور ls را اجرا میکنید در واقع یک process را شروع کرده‌اید.
سیستم برای هر process یک شناسه پنج رقمی در نظر میگیرد که به آن process id یا pid میگویند. هر process در یونیکس یک شناسه منحصربه‌فرد دارد. و در هر زمان هر pid تنها به یک process اختصاص پیدا میکند. در واقع pid یک عدد ۱۶بیتی است که میتواند حداکثر تا ۳۲۷۶۷ باشد.
دو روش برای شروع هر process وجود دارد. اجرای آن در foreground یا background.

Foreground Processes

به طور پیش فرض تمام دستورات به این طریق اجرا میشوند. در صورت نیاز از ورودی میخوانند یا در خروجی مینویسند.به عنوان مثال پس از اجرای دستور ls خروجی دستور بر روی صفحه نمایش هدایت می‌شود. (هدایت ورودی و خروجی‌‌ها در فصل ۱۳ به طور کامل بررسی میشود). در زمانی که این دستور در حال اجرا است، شما نمیتوانید هیچ دستور دیگری را شروع کنید. البته در این حالت میتوان دستورات را وارد کرد و سیستم‌عامل دستورات را به عنوان buffer ذخیره میکند تا دستور فعلی پایان یابد، ولی تا زمانی که اجرای دستور حاضر پایان نیابد، اجرای هیچ دستور دیگری شروع نمیشود.
خوشبختانه در یونیکس امکان فرستادن دستورات به background یا تعلیق آنها وجود دارد.

Background Processes

در این حالت دستور در پس زمینه اجرا می‌شود و شما قادر به وارد کردن دستورات بعدی هستید. مزیت استفاده از این روش دراینست که شما نیاز به صبر کردن برای اتمام دستور جاری ندارید.
ساده ترین راه برای اجرای یک دستور در background استفاده از کاراکتر & در آخر هر دستور است.

نکته: در صورتی که دستوری که به background فرستاده شده نیاز به ورودی داشته باشد، اجرای آن متوقف شده و تا زمانی که ورودی خود را دریافت کند منتظر میماند.


مثال:

$ ls ch0*.doc &

خروجی این دستور یک عدد مشابه زیر است:

[1] 20757

این عدد (در اینجا ۲۰۷۵۷) نمایانگر pid این دستور و [1] نشان‌دهنده‌ی‌ job number میباشد. شما نیاز به دانستن job number برای جابجا کردن دستورات از backgroun به foreground دارید.
پس از اتمام دستور پیغامی به شکل زیر دریافت خواهید کرد:

[1] + Done ls ch0*.doc


اشاره: در صورتی که بعد از پایان دستور شما پیغامی مشاهده نکردید، میتوانید با دستور زیر آنرا فعال کنید:

$ set -o monitor

و برای غیرفعال کردن آن از +o استفاده کنید:

$ set +o monitor

همچنین برای نمایش تمامی آپشن‌ها میتوانید از

$ set -o

استفاده کنید.



ولی خروجی شما در صورتی که دستور با خطا مواجه شود چیزی متفاوت با حالت قبل خواهد بود.
مثال:

$ ls no_such_file &

که خروجی به شکل زیر را تولید میکند:

[1] 25389
$ no_such_file: No such file or directory

خط اول اطلاعات process و خط بعدی نشان دهنده‌ی خطای حاصل از اجرای این دستور است که دقیقا مشابه با حالتی است که دستور در foreground اجرا میشود.
و در صورتی که نمایش خروجی حاصل از اتمام دستور فعال باشد (که در بالا به آن اشاره شد) با زدن کلید اینتر خروجی زیر بر روی صفحه‌ی نمایش ظاهر میشود:

[1] + Done(2)		 ls no_such_file &

در این حالت دستور ls یک وضعیت غیر صفر را برمیگرداند. مقدار ۲ در این پیغام نمایان‌گر این است که اجرای دستور با موفقیت انجام نشده است.


فرستادن یک دستور از foreground به background

علاوه‌بر اینکه میتوان دستورات را با استفاده از & در background اجرا کرد، میتوان دستورات foreground را نیز به background فرستاد. برای این منظور میتوان از کلیدهای ترکیبی ctrl+z استفاده نموند که موجب تعلیق و فرستادن process به background میشود. در این حالت دستور در حافظه قرار دارد ولی پردازشی بر روی آن انجام نمیشود.

اجرای مجدد دستورات

برای اجرا مجدد دستوراتی که تعلیق شده‌اند یا به background فرستاده شده‌اند دو دستور bg و fg میتوان استفاده کرد.


دستور bg

از این دستور برای اجرای مجدد دستوری استفاده میشود که تعلیق شده است.
شکل کلی این دستور به شکل زیر است:

$ bg %jobnumber

که در آن jobnumber شماره دستوری است که به پس زمینه فرستاده شده است.

مثال: فرض کنید دو دستور به شکل زیر درحین استفاده با استفاده ctrl+z تعلیق شوند.

$ long_running_process
^Z[1] + Stopped (SIGTSTP) 		long_running_process
$ long_running_process2
^Z[2] + Stopped (SIGTSTP) 		long_running_process2

و دستورات زیر به ترتیب موجب اجرای مجدد دستور اول و دوم میشوند:

$ bg %1
[1] 	long_running_process &
$ bg %2
[2]		long_running_process2 &


نکته: به جای عبارت bg %1 میتوان از bg به تنهایی نیز استفاده نموند.


دستور fg

با استفاده از این دستور میتوان، processهایی که اجرای آنها تعلیق شده و به background فرستاده شده‌اند را دوباره به foreground آورد و به حالت اجرا درآورد.
شکل کلی این دستور به صورت زیر است:

$ fg %jobnumber

مثال:

$ long_running_process
^Z[1] + Stopped (SIGTSTP)

که با استفاده از دستور fg %1 یا fg میتوان اجرای آنرا مجددا به foreground منتقل کرد.

$ fg %1
long_running_process

دستور nohup

دستور nohup یا "no hang up" برای محافظت از اجرای یک دستور زمانی که به هر دلیل در حین اجرای دستور، سیستم شما log off یا disconnect میشود، میتوان استفاده کرد.
شکل کلی این دستور به صورت زیر است:

$ nohup command

مثال:

$ nohup ls -a &
[1] 8925
$ nohup: ignoring input and appending output to `nohup.out'

که در این حالت خروجی دستور در فایل nohup.out ذخیره خواهد شد.


دستور wait

از این دستور برای صبر کردن تا اجرای کامل یک دستور در background استفاده میشود. سه شکل برای استفاده از این دستور وجود دارد:

  1. بدون option (حالت پیش فرض)
  2. استفاده با pid
  3. استفاده با job number به همراه علامت درصد (٪)

در حالت اول(پیش فرض و بدون آپشن) سیستم هیچ دستور جدیدی را دریافت نمیکند. و آنقدر منتظر میماند تا اجرای تمام دستورات در background پایان یابد.
و در دوحالت بعدی فقط منتظر پایان یافتن دستوری که pid یا job number آن به دستور داده شده می‌ماند.

مثال:

$ wait %1

تا زمانی که اجرای این دستور پایان نیابد، شما قادر به وارد کردن هیچ دستور جدیدی نیستید.

نکته: در مثال‌های قبل پیغام Done به معنی اتمام دستور نمایش داده میشد ولی در این حالت پیغامی نمایش داده نمیشود


لیست processهای در حال اجرا

برای این منظور میتوان از دو دستور jobs و ps استفاده کرد.

دستور jobs

از این دستور برای نمایش processهای تعلیق شده یا موجود در background استفاده میشود.
مثال:

$jobs
[3] + Running 				first_one &
[2] - Stopped (SIGTSTP) 	second_one
[1]   Stopped (SIGTTIN) 	third_one & 

نکته: وجود علامت‌های + و - در این لیست به این دلیل است که پس از اتمام یک process، یا شروع process جدید، شماره‌ی دستورات جابجا میشود.


دستور ps

از این دستور میتوان برای نمایش تمام processهای در حال اجرا استفاده کرد.


استفاده از ps به تنهایی

در حالت شما تنها دستوراتی که خودتان آغازشان کرده‌اید را مشاهده میکنید.
مثال:

$ ps
 PID TTY          TIME CMD
10747 pts/0    00:00:00 bash
10827 pts/0    00:00:00 top
10870 pts/0    00:00:00 seq
10872 pts/0    00:00:00 ps

در این حالت برای هر دستور چهار ستون اطلاعات مشخص میشود.
اولین ستون pid پروسه است.
در ستون دوم tty به معنی اجرای دستور به وسیله‌ی ترمینال است.
در ستون سوم time نشان‌دهنده‌ی زمان پردازش cpu برای انجام این process است.
و در آخر نام process مشخص شده است.


استفاده از آپشن (f (full

این حالت نیز مشابه حالت قبل دستوراتی که توسط شما آغاز شده‌اند را نمایش میدهد با این تفاوت که هشت ستون از اطلاعات را برای هر process نمایش میدهد.
مثال:

$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
baroon   11638 11633  8 15:17 pts/0    00:00:00 bash
baroon   12026 11638  1 15:24 pts/0    00:00:00 seq 200000
baroon   11693 11638  0 15:17 pts/0    00:00:00 ps -f

چهار ستون جدید در این حالت به شرح زیر هستند:

  1. uid  : User id
  2. ppid  : parent process id (در بخش بعد توضیح داده میشود)
  3. c  : cpu درصد استفاده از
  4. stime : زمان شروع پردازش

توجه کنید مقدار عدد ppid برای تمام پردازش ها برابر با pid پروسه bash هستند. یا به عبارتی bash والد تمام این processها میباشد.

استفاده از آپشن‌های aux

از این آپشن برای مشاهده‌ی تمام processهای موجود در سیستم‌عامل استفاده میشود. توجه کنید که در این حالت از - برای آپشن استفاده نمیشود و دستور به شکل ps aux است.
برای مشاهده‌ی تمام آپشن‌ها به man ps مراجعه کنید.

توقف اجرای processها با استفاده از دستور kill

در دو حالت میتوان از دستور kill برای کشتن processها استفاده کرد.

توقف با استفاده از job number

شکل استفاده از دستور در این حالت به صورت زیر است:

#kill %jobnumber

مثال:

#kill %1
[1] - Terminated 	third_one &
$


توقف با استفاده از pid

شکل دستور از دستور در این حالت به صورت زیر است:

#kill pid

مثال:

$ kill 6739
$

نکته: توجه کنید در این شکل از دستور kill، به صورت فیزیکی اجرای process متوقف نمیشود. بلکه این دستور تنها یک سیگنال(سیگنال TERM با مقدار ۱۵) مبتنی بر اتمام اجرای process به آن برنامه میفرستد. که برنامه میتواند آن‌را مد نظر قرار داده و متوقف شود یا آنرا نادیده گرفته و به کار خود ادامه دهد.


در صورتی که به طور قطعی نیاز به بستن یک process باشد میتوان از دستور kill با یکی از دو آپشن زیر استفاده کرد:

kill -9 [pid or jobnumber]
kill -KILL [pid or jobnumber]


اخطار: در اجرای این دستور بسیار مراقب باشید.



پروسه‌های والد و فرزند

در بخش قبل و هنگامی که دستور ps را آپشن f اجرا کردید، مشاهده کردید که هر process، یک شماره process id و یک شماره parent process id دارد. هر process در سیستم یک والد(parent) دارد. به طوری که والد اکثر دستورات shell، و والد shell سیستم‌عامل است.

به عنوان مثال

UID        PID  PPID  C STIME TTY          TIME CMD
baroon   15266 15261  0 16:36 pts/0    00:00:00 bash
baroon   15321 15266  0 16:36 pts/0    00:00:00 top
baroon   15329 15266  1 16:36 pts/0    00:00:00 seq 200000
baroon   15335 15266  0 16:36 pts/0    00:00:00 ps -f

نشان میدهد تمام processهایی که آغازه شده‌اند، فرزند bash هستند.

نکته: زمانی که process فرزند انشعاب یا ایجاد میشود، تمام محیط والد خود شامل متغیرهای محیطی (environment variables) را نیز به دریافت میکند. یک فرزند میتواند محیط خود را تغییر دهد ولی این تغییرات تاثیری در محیط والد ندارد.






Eman ‏۱۵ فوریهٔ ۲۰۱۲، ساعت ۱۱:۵۱ (UTC)

ابزارهای شخصی
گویش‌ها
فضاهای نام
عملکردها
گشتن
کتاب‌ها
مقاله‌ها
جعبه‌ابزار