Tín hiệu (Signals) là ngắt (interrupts) được gửi đến tiến trình bởi hệ điều hành, có thể chấm dứt chương trình sớm. Bạn có thể tạo ngắt bằng Ctrl+C trên UNIX, LINUX, Mac OS X hoặc Windows.
Có tín hiệu không thể bắt được bởi chương trình, nhưng dưới đây là danh sách các tín hiệu có thể bắt và xử lý. Chúng được định nghĩa trong header C++:
| Tín hiệu | Mô tả |
|---|---|
| SIGABRT | Kết thúc bất thường của chương trình, ví dụ gọi abort. |
| SIGFPE | Phép toán số học sai, như chia cho 0 hoặc tràn số. |
| SIGILL | Phát hiện lệnh không hợp lệ. |
| SIGINT | Nhận tín hiệu chú ý tương tác (Ctrl+C). |
| SIGSEGV | Truy cập bộ nhớ không hợp lệ. |
| SIGTERM | Yêu cầu kết thúc gửi đến chương trình. |
Hàm signal()
Thư viện xử lý tín hiệu C++ cung cấp hàm signal để bắt sự kiện bất ngờ. Cú pháp:
void (*signal (int sig, void (*func)(int)))(int);
Đơn giản hóa: hàm nhận hai tham số: đầu tiên là số nguyên đại diện cho số tín hiệu, thứ hai là con trỏ đến hàm xử lý tín hiệu.
Ví dụ bắt tín hiệu SIGINT bằng signal():
Ví dụ
#include <iostream>
#include <csignal>
using namespace std;
void signalHandler(int signum) {
cout << "Interrupt signal (" << signum << ") received.\n";
// dọn dẹp và đóng tài nguyên ở đây
// kết thúc chương trình
exit(signum);
}
int main() {
// đăng ký tín hiệu SIGINT và hàm xử lý
signal(SIGINT, signalHandler);
while (1) {
cout << "Going to sleep...." << endl;
sleep(1);
}
return 0;
}
Kết quả
Going to sleep.... Going to sleep.... Going to sleep....
Sau khi nhấn Ctrl + C:
Going to sleep.... Going to sleep.... Going to sleep.... Interrupt signal (2) received.
Hàm raise()
Có thể sinh tín hiệu bằng hàm raise(), nhận số nguyên là số tín hiệu:
int raise (signal sig);
Ví dụ sinh tín hiệu nội bộ bằng raise():
Ví dụ
#include <iostream>
#include <csignal>
using namespace std;
void signalHandler(int signum) {
cout << "Interrupt signal (" << signum << ") received.\n";
exit(signum);
}
int main() {
int i = 0;
signal(SIGINT, signalHandler);
while (++i) {
cout << "Going to sleep...." << endl;
if (i == 3) {
raise(SIGINT);
}
sleep(1);
}
return 0;
}
Kết quả
Going to sleep.... Going to sleep.... Going to sleep.... Interrupt signal (2) received.