C++信号处理

C++信号处理是指在程序运行过程中对异步事件(如错误、中断或其他条件)的响应。这些异步事件通常由操作系统发送信号给进程。C++标准库并没有直接提供信号处理的机制,但你可以使用操作系统提供的API来实现信号处理。

在Unix-like系统(如Linux)中,信号处理通常使用signal函数或sigaction函数。在Windows系统中,则使用SetConsoleCtrlHandler函数或其他相关的API。

Unix-like系统中的信号处理

使用signal函数

signal函数是处理信号的一种简单方式,但它提供的控制有限。它的原型如下:

cpp 复制代码
#include <csignal>

void (*signal(int signum, void (*handler)(int)))(int);

signum参数是要处理的信号编号,handler参数是一个函数指针,指向处理该信号的函数。

例如,你可以设置一个处理SIGINT信号(通常由用户按下Ctrl+C触发)的函数:

cpp 复制代码
#include <iostream>
#include <csignal>

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

    // 清理并关闭
    exit(signum);
}

int main() {
    // 注册信号SIGINT的处理函数
    signal(SIGINT, signalHandler);

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

    return 0;
}
使用sigaction函数

sigaction函数提供了比signal更强大和灵活的信号处理方式。它的原型如下:

cpp 复制代码
#include <signal.h>

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

struct sigaction结构体定义了信号处理的行为:

cpp 复制代码
struct sigaction {
    void (*sa_handler)(int);
    void (*sa_sigaction)(int, siginfo_t *, void *);
    sigset_t sa_mask;
    int sa_flags;
    void (*sa_restorer)(void);
};

例如,使用sigaction来设置SIGINT信号的处理函数:

cpp 复制代码
#include <iostream>
#include <signal.h>
#include <unistd.h>

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

int main() 
{
    struct sigaction sa;
    sa.sa_handler = signalHandler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;

    sigaction(SIGINT, &sa, NULL);

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

    return 0;
}

Windows系统中的信号处理

在Windows系统中,信号处理的概念与Unix-like系统不同。Windows使用事件来处理异步操作。你可以使用SetConsoleCtrlHandler函数来设置控制台应用程序的信号处理函数。例如:

cpp 复制代码
#include <iostream>
#include <windows.h>

BOOL WINAPI ConsoleHandler(DWORD dwCtrlType) 
{
    switch(dwCtrlType) {
        case CTRL_C_EVENT:
        case CTRL_BREAK_EVENT:
        case CTRL_CLOSE_EVENT:
            std::cout << "Console event detected." << std::endl;
            return TRUE; // 返回TRUE表示已经处理了事件
    }
    return FALSE; // 返回FALSE表示未处理事件,系统将执行默认操作
}

int main() 
{
    SetConsoleCtrlHandler(ConsoleHandler, TRUE);

    while(1) {
        std::cout << "Going to sleep..." << std::endl;
        Sleep(1000);
    }

    return 0;
}

在这个例子中,ConsoleHandler函数会在接收到Ctrl+C、Ctrl+Break或关闭控制台窗口的事件时被调用。

相关推荐
无 证明2 小时前
new 分配空间;引用
数据结构·c++
别NULL6 小时前
机试题——疯长的草
数据结构·c++·算法
CYBEREXP20087 小时前
MacOS M3源代码编译Qt6.8.1
c++·qt·macos
yuanbenshidiaos8 小时前
c++------------------函数
开发语言·c++
yuanbenshidiaos8 小时前
C++----------函数的调用机制
java·c++·算法
tianmu_sama8 小时前
[Effective C++]条款38-39 复合和private继承
开发语言·c++
羚羊角uou8 小时前
【C++】优先级队列以及仿函数
开发语言·c++
姚先生978 小时前
LeetCode 54. 螺旋矩阵 (C++实现)
c++·leetcode·矩阵
FeboReigns9 小时前
C++简明教程(文章要求学过一点C语言)(1)
c语言·开发语言·c++
FeboReigns9 小时前
C++简明教程(文章要求学过一点C语言)(2)
c语言·开发语言·c++