关于sigsetjmp和siglongjmp

本文详细解析了sigsetjmp和siglongjmp在C语言中的使用方法,通过一个简单的例子展示了如何利用这两个函数在接收到特定信号时执行特定操作,同时保存并恢复程序的上下文。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在CSAPP上看到的例子:

#include<iostream>
#include<signal.h>
#include <setjmp.h>
#include<unistd.h>

sigjmp_buf buf;

void handler(int sig){
    std::cout << "hi\n";
    siglongjmp(buf, 3);
}

int main(){

    signal(SIGINT, handler);

    if(!sigsetjmp(buf, 1))
        std::cout << "starting\n";
    else
        std::cout << "restarting\n";

    while(1){
        sleep(1);
        std::cout << "processing...\n";
    }
}

代码简单,sigsetjmp设置一个点,当进程收到SIGINT信号即调用信号处理函数,调用siglongjmp返回sigsetjmp设置的点

因为次两个函数被认为风格不好,所以当时i没注意其原理。

其实背后的原理是:sigsetjmp把进程运行的上下文(栈帧,信号,环境变量等东西)保存在buf里,使得siglongjmp返回时可以在buf中回复进程的上下文。于是进程就“跳”到了sigsetjmp保存buf的点

### 使用 `setjmp` `siglongjmp` 的注意事项 在C编程中,`setjmp` 函数用于保存程序当前的执行环境到一个特定的位置,而 `siglongjmp` 则用来恢复之前由 `setjmp` 保存下来的环境状态并继续执行。当涉及到信号处理时,推荐使用 `sigsetjmp` 而不是普通的 `setjmp` 来配合 `siglongjmp` 进行非局部跳转操作[^1]。 这是因为标准库中的 `setjmp` 可能不会保留关于阻塞或未决信号的信息,在某些情况下这可能会导致不可预测的行为;相反,`sigsetjmp` 提供了一个标志参数来控制是否要保存这些额外的状态信息,从而使得与 `siglongjmp` 结合更加安全可靠[^2]。 下面是一个简单的例子展示如何正确地将两者结合起来: ```c #include <stdio.h> #include <setjmp.h> #include <signal.h> static jmp_buf env; void handler(int signum){ printf("Caught signal %d\n",signum); siglongjmp(env, 1); // 非本地返回至调用sigsetjmp处 } int main(){ struct sigaction sa; sa.sa_handler = &handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; if (sigaction(SIGINT,&sa,NULL) == -1){ perror("Error setting signal action"); return 1; } int ret_val=sigsetjmp(env, 1); if(ret_val==0){ puts("Press Ctrl+C to trigger the jump..."); while(1){} /* Infinite loop until SIGINT is caught */ }else{ puts("Returned from longjump!"); } } ``` 在这个实例里,通过设置SIGINT(通常是Ctrl+C触发)的动作指向自定义处理器函数,并在此函数内部调用了 `siglongjmp()` 。如果一切正常,则按下Ctrl+C之后会跳出无限循环回到最初调用 `sigsetjmp()` 后面的地方继续往下走。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值