ubuntu在代码中添加异常信号捕获防止异常退出(可用于多线程程序)

1.异常信号捕获:

在代码运行处理大批量数据时,往往不想因为某一个数据的文件损坏或异常导致代码的运行退出或异常重启,影响系统运行的稳定性。而这些异常又不能够被try catch捕获到,因此在某些特殊应用中,需要进行异常信号的捕获,如SIGSEGV信号、SIGABRT 信号。这些异常信号的捕获在单线程中往往很容易实现,但在复杂的项目中往往需要多个线程,若想实现单个线程只捕获自己线程内的异常,并继续处理的功能,需要对信号进行分隔开,防止串线程,导致程序的意外退出。以下是代码实现示例:

#include <csignal>
#include <cstdlib>
#include <csetjmp>

thread_local JumpBuffer jumpBuffer_thread_1;
thread_local JumpBuffer jumpBuffer_thread_2;

void signalHandlerThread1(int signal, siginfo_t *info, void *context) {
    std::cerr << "Caught signal " << signal << " (segmentation fault)" << std::endl;
    std::cerr << "Signal origin: " << info->si_addr << std::endl;
    // 恢复执行到上次设置的跳转点
    siglongjmp(jumpBuffer.get(), 1);
}

void setupSignalHandlerThread1() {
    struct sigaction sa{};
    sa.sa_flags = SA_SIGINFO;
    sa.sa_sigaction = signalHandlerThread1;
    // 注册信号处理函数(目前只捕获了(SIGABRT)6和(SIGSEGV)11两种信号)
    if (sigaction(SIGSEGV, &sa, nullptr) == -1) {
        std::cerr << "线程1,Failed to set signal handler" << std::endl;
    }else if(sigaction(SIGABRT , &sa, nullptr) == -1){
        std::cerr << "线程1,Failed to set signal handler" << std::endl;
    }
    // add others signal
}

// cxy20240713 异常信号捕获,出现异常时不要退出程序,继续执行(只捕获引擎检测线程的信号)
void signalHandlerThread2(int signal, siginfo_t *info, void *context) {
    std::cerr << "Caught signal " << signal << " (segmentation fault)" << std::endl;
    std::cerr << "Signal origin: " << info->si_addr << std::endl;
    // 恢复执行到上次设置的跳转点
    siglongjmp(jumpBuffer_engine.get(), 1);
}

void setupSignalHandlerThread2() {
    struct sigaction sa{};
    sa.sa_flags = SA_SIGINFO;
    sa.sa_sigaction = signalHandlerThread2;

    // 注册信号处理函数(目前只捕获了(SIGABRT)6和(SIGSEGV)11两种信号)
    if (sigaction(SIGSEGV, &sa, nullptr) == -1) {
        std::cerr << "线程2,Failed to set signal handler" << std::endl;
    }else if(sigaction(SIGABRT , &sa, nullptr) == -1){
        std::cerr << "线程2,Failed to set signal handler" << std::endl;
    }
    // add others signal
}

void function1()
{
	// process1
	setupSignalHandlerThread1();
	if(sigsetjmp(jumpBuffer_thread_1.get(), 1) == 0){
		function1_process();
	}
	
}

void function2()
{
	// process2
	setupSignalHandlerThread2();
	if(sigsetjmp(jumpBuffer_thread_2.get(), 1) == 0){
		function2_process();
	}
}


int main()
{
	std::thread Handler1(function1);    //线程1
    std::thread Handler2(function2);    //线程2
    //other process ...
    Handler1.join();      
    Handler1.join();              
    return 0;
}

上述代码分别在两个线程中捕获了各自线程的异常信号,并在捕获到异常时,程序的运行跳转到指定的位置,即setupSignalHandlerThread1();setupSignalHandlerThread2();函数位置,进行继续运行。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值