C++信号处理器编程

信号是操作系统向进程发送的异步通知。C++标准库提供了signal函数注册信号处理器,用于处理中断、终止等异常情况。

基本的信号处理使用std::signal注册处理器。

#include
#include
#include
#include

std::atomic interrupt_flag(false);

void signal_handler(int signum) {
std::cout << "Signal " << signum << " received\n";
interrupt_flag.store(true);

if (signum == SIGTERM) {
std::cout << "Termination requested\n";
} else if (signum == SIGINT) {
std::cout << "Interrupt received (Ctrl+C)\n";
}
}

void register_signal_handlers() {
std::signal(SIGINT, signal_handler);
std::signal(SIGTERM, signal_handler);

std::cout << "Signal handlers registered. Press Ctrl+C to trigger.\n";
std::cout << "Sending SIGTERM for demonstration...\n";

std::raise(SIGTERM);

if (interrupt_flag.load()) {
std::cout << "Interrupt flag was set\n";
}
}

忽略和重置信号处理。

void ignore_signal() {
std::signal(SIGINT, SIG_IGN);
std::cout << "SIGINT ignored. Press Ctrl+C (will be ignored).\n";
}

void default_signal() {
std::signal(SIGINT, SIG_DFL);
std::cout << "SIGINT reset to default.\n";
}

信号处理器的限制。

class SignalSafe {
public:
static void handler(int signum) {
const char msg[] = "Signal-safe handler\n";
write(STDERR_FILENO, msg, sizeof(msg));
}
};

volatile sig_atomic_t signal_received = 0;

void safe_signal_handler(int signum) {
signal_received = signum;
}

void safe_handler_demo() {
std::signal(SIGINT, safe_signal_handler);

std::raise(SIGINT);

if (signal_received != 0) {
std::cout << "Signal " << signal_received << " was received and recorded\n";
signal_received = 0;
}
}

使用sigaction设置高级信号处理。

void sigaction_example() {
struct sigaction sa;
sa.sa_handler = safe_signal_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;

if (sigaction(SIGINT, &sa, nullptr) == -1) {
std::cerr << "sigaction failed\n";
} else {
std::cout << "sigaction set up\n";
}
}

自定义退出处理使用atexit。

void cleanup_function() {
std::cout << "Cleanup function called\n";
}

void atexit_example() {
std::atexit(cleanup_function);
std::atexit([]() {
std::cout << "Lambda cleanup\n";
});

std::cout << "Exiting normally...\n";
}

void atexit_demo() {
atexit_example();
}

abort和exit的区别。

void abort_exit_demo() {
std::cout << "Calling exit() - cleanup runs...\n";
}

信号集操作。

void sigset_example() {
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigaddset(&set, SIGTERM);

if (sigismember(&set, SIGINT)) {
std::cout << "SIGINT is in the set\n";
}

sigdelset(&set, SIGINT);
if (!sigismember(&set, SIGINT)) {
std::cout << "SIGINT removed from set\n";
}
}

信号屏蔽阻止特定信号传递。

void signal_block_example() {
sigset_t block_set;
sigemptyset(&block_set);
sigaddset(&block_set, SIGINT);

sigprocmask(SIG_BLOCK, &block_set, nullptr);
std::cout << "SIGINT blocked\n";

sigprocmask(SIG_UNBLOCK, &block_set, nullptr);
std::cout << "SIGINT unblocked\n";
}

信号处理器应该保持简单,只设置标志变量,避免复杂操作。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐