فصل ششم - پروسسها
مقدمه
شما در این فصل مفهوم 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 استفاده میشود. سه شکل برای استفاده از این دستور وجود دارد:
- بدون option (حالت پیش فرض)
- استفاده با pid
- استفاده با 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
چهار ستون جدید در این حالت به شرح زیر هستند:
- uid : User id
- ppid : parent process id (در بخش بعد توضیح داده میشود)
- c : cpu درصد استفاده از
- 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)