مدیریت سیگنال‌ها در ++C

سیگنال‌ها وقفه‌هایی (interrupt) هستند که از جانب سیستم عامل به یک پروسس (process) تحویل داده می‌شوند و می‌توانند یک برنامه را به صورت دائمی‌ پایان دهند. می‌توان با فشردن کلید Ctrl+C در لینوکس، یونیکس، Mac OS X یا ویندوز یک وقفه ایجاد کرد.

سیگنال‌هایی وجود دارند که یک برنامه نمی‌تواند آنها را دریافت کند. اما لیستی از سیگنال‌ها در زیر آمده است که برنامه توانایی دریافت آنها و ایجاد واکنش مناسب نسبت به آنها را دارد. این سیگنال‌ها در هدرفایل <csignal> تعریف شده‌اند.

ردیف

سیگنال و توصیف آن

1

SIGABRT

خاتمه غیرعادی یک برنامه، مانند فراخوانی abort.

2

SIGFPE

یک عملیات ریاضی نادرست، مانند تقسیم بر صفر یا عملیات منجر به سرریزی (overflow).

3

SIGILL

شناسایی یک دستور غیرمجاز.

4

SIGINT

دریافت یک سیگنال interactive attention.

5

SIGSEGV

یک دسترسی غیرمجاز به حافظه.

6

SIGTERM

ارسال یک درخواست پایان برنامه  به خود برنامه.

تابع ()signal

کتابخانه مدیریت سیگنال‌ها تابع signal را برای مدیریت رویدادهای غیرمنتظره فراهم کرده است.  ساختار تابع signal در زیر آمده است.

void (*signal (int sig, void (*func)(int)))(int); 

این تابع دو آرگومان دریافت می‌کند، اولین آرگومان، یک عدد صحیح بوده که شماره سیگنال را بیان می‌کند و آرگومان دوم یک اشاره‌گر به تابع مدیریت کننده سیگنال می‌باشد.

حال بیاید یک برنامه ساده ++C بنویسیم که با استفاده از تابع ()signal، سیگنال SIGINT را دریافت می‌کند. برای دریافت کردن هر سیگنالی، باید با استفاده از تابع signal خود سیگنال و تابع مدیریت کننده آن را ثبت کنید. مثال زیر این موضوع را روشن می‌کند.

#include <iostream>
#include <csignal>

using namespace std;

void signalHandler( int signum ) {
   cout << "Interrupt signal (" << signum << ") received.\n";

   // cleanup and close up stuff here  
   // terminate program  

   exit(signum);  
}

int main () {
   // register signal SIGINT and signal handler  
   signal(SIGINT, signalHandler);  

   while(1) {
      cout << "Going to sleep...." << endl;
      sleep(1);
   }

   return 0;
}

با اجرای این کد، خروجی زیر بدست می‌آید.

Going to sleep....
Going to sleep....
Going to sleep....

حال، کلید Ctrl+C را فشار داده تا در برنامه شما وقفه افتاده و نحوه دریافت سیگنال توسط برنامه و خروجی پس از آن را ملاحظه کنید.

Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.

تابع ()raise

با استفاده از تابع ()raise می‌توان یک سیگنال تولید کرد. این تابع یک آرگومان عدد صحیح به عنوان شماره سیگنال دریافت می‌کند. ساختار این تابع به صورت زیر است.

int raise (signal sig);

در این عبارت، sig می‌تواند شماره سیگنال یکی از این سیگنال‌هایی باشد که قصد تولید آن را داریم: SIGINT, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGTERM, SIGHUP.

در مثال زیر یک سیگنال را با استفاده از تابع ()raise ایجاد می‌کنیم.

#include <iostream>
#include <csignal>

using namespace std;

void signalHandler( int signum ) {
   cout << "Interrupt signal (" << signum << ") received.\n";

   // cleanup and close up stuff here  
   // terminate program  

   exit(signum);  
}

int main () {
   int i = 0;
   // register signal SIGINT and signal handler  
   signal(SIGINT, signalHandler);  

   while(++i) {
      cout << "Going to sleep...." << endl;
      if( i == 3 ) {
         raise( SIGINT);
      }
      sleep(1);
   }

   return 0;
}

با اجرای این کد، خروجی زیر حاصل شده و به صورت خودکار از برنامه خارج می‌شود.

Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.

منبع: ترجمه از سایت tutorialspoint.com

امیدوارم آموزش مدیریت سیگنال‌ها در ++C براتون مفید واقع شده باشه. اگر علاقمند بودید دیگر جلسات آموزش زبان ++C را هم مطالعه کنید.

اگر این نوشته‌ برایتان مفید بود لطفا کامنت بنویسید.

مطالعه دیگر جلسات این آموزش<< جلسه قبلی                    جلسه بعدی >>
مطلب پیشنهادی:  فایل‌ها و استریم‌ها در ++C

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *