Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C++

Xử lý tín hiệu (Signal Handling) trong C++


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ả
SIGABRTKết thúc bất thường của chương trình, ví dụ gọi abort.
SIGFPEPhép toán số học sai, như chia cho 0 hoặc tràn số.
SIGILLPhát hiện lệnh không hợp lệ.
SIGINTNhận tín hiệu chú ý tương tác (Ctrl+C).
SIGSEGVTruy cập bộ nhớ không hợp lệ.
SIGTERMYê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.