zoukankan      html  css  js  c++  java
  • 信号处理函数的返回setjmp/longjmp

    信号处理函数可以正常返回,也可以调用其他函数返回到程序的主函数中,而不是从该处理程序返回。

    正如ANSI C标准所说明的,一个信号处理程序可以返回或者调用abort、exit或longjmp(goto不支持跳出它所在的函数,

    因此不能用来从信号处理程序返回到主函数中)。

     

    int setjmp(jmp_buf env);

    int sigsetjmp(sigjmp_buf env, int savesigs);

    void longjmp(jmp_buf env, int val);

    void siglongjmp(sigjmp_buf env, int val);

    使用longjmp可以跳转到setjmp设置的位置。

    参数env是一个特殊类型jmp_buf的变量。这一数据类型是某种形式的数组,其中存放的是在调用longjmp时能用来恢复栈状态的所有信息。

    一般来说env是一个全局变量,因为需从另一个函数中引用它。我们可以在希望返回的位置使用setjmp,直接调用setjmp时返回0;当从longjmp

    返回时,setjmp的返回值是longjmp的第二个参数的值,可以利用这一点使多个longjmp返回到一个setjmp处。

    用法演示:

    #include <stdio.h>
    #include <signal.h>
    #include <setjmp.h>
    
    
    jmp_buf env;
    
    void hand_min15(int);
    void hand_max9(int);
    
    
    int main()
    {
        switch(setjmp(env))
        {
            case 0:
            {
       printf("setjmp ");
    break; } case 1: { printf("return from min+15 "); break; } case 2: { printf("return from max-9 "); break; } default: break; } signal(SIGRTMIN+15, hand_min15); signal(SIGRTMAX-9, hand_max9); printf("wait for signal "); while(1); return 0; } void hand_min15(int sig_num) { longjmp(env, 1); printf("recv min+15 "); return; } void hand_max9(int sig_num) { longjmp(env, 2); printf("recv max-9"); return; }

    信号处理函数没有正常返回,而是调用了longjmp直接跨函数跳转,返回到setjmp处。

    kill -s SIGRTMIN+15 5301
    kill -s SIGRTMIN+15 5301
    kill -s SIGRTMAX-9 5301
    kill -s SIGRTMAX-9 5301

    输出结果:

    setjmp

    wait for signal
    return from min+15
    wait for signal
    return from max-9
    wait for signal

    在第二次kill -s SIGRTMIN+15 5301 时,没有输出内容。原因:

    信号处理时会自动屏蔽正在被处理的信号,在信号处理函数返回时把进程的信号屏蔽字恢复。即解除对当前信号的阻塞。

    上面的代码中没有让信号处理函数正常返回,而是用longjmp直接跳转,所以进程的信号屏蔽字在第一次收到信号后,就把

    信号设置为阻塞并且再也没有恢复,因而再也触发不了信号处理函数了,除非手动将进程对信号的屏蔽去除。如果既想使用

    跨函数跳转直接返回,又想避免每次都手动清除信号屏蔽的麻烦,就要使用:

    int sigsetjmp(sigjmp_buf env, int savesigs);

    void siglongjmp(sigjmp_buf env, int val);

  • 相关阅读:
    挺好的程序员面试网址
    [转]浅谈协方差矩阵
    坚持
    matlab中文论坛
    看书
    Opengl绘制点
    说服力
    心情
    vector操作
    我的毕设
  • 原文地址:https://www.cnblogs.com/zhangxuan/p/6677772.html
Copyright © 2011-2022 走看看