Chinaunix首页 | 论坛 | 博客
  • 博客访问: 49416
  • 博文数量: 5
  • 博客积分: 1421
  • 博客等级: 上尉
  • 技术积分: 78
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-13 00:12
文章分类

全部博文(5)

文章存档

2010年(5)

我的朋友

分类: C/C++

2010-01-19 13:31:40

文件: sigsetjmp.tar.gz
大小: 0KB
下载: 下载
   最近阅读telnet源码时看到了函数sigsetjmp和siglongjmp的使用,因以前没有使用过,故查阅了相关资料,将心得整理如下:
   函数原型: 
      int sigsetjmp(sigjmp_buf env, int savesigs);
      void siglongjmp(sigjmp_buf env, int val);

   man 手册中关于函数的描述:
    setjmp() saves the stack context/environment in env for later use by longjmp(3).sigsetjmp() is similar to setjmp(). If savesigs is non-zero, the set of blocked signals is saved in env and will be restored if a siglongjmp(3) is later performed with this env.


   网上关于sigsetjmp & siglongjmp的使用例子已经很多,但我觉得他们少写了一点,至少这于我这种才使用该函数的人是很重要的,而且telnet源码中也使用了此方法。网上的例子都是在同一源文件的不同函数中使用sigsetjmp & siglongjmp,但我觉得这种例子还不能完全明白的诠释出它们的用法。因为用goto也能达到同样目的。下面,是在两个不同源文件例用sigsetjmp & siglon-gjmp的例子,希望对各位能有所帮助。

源文件A:sigsetjmp.c
#include
#include
#include
sigjmp_buf sigBuf;
void FunA()
{
    printf("Enter FunA!\n");
    call();
    printf("Exit FunA!\n");
}

int main(int argc,char *argv[])
{
    int iRet = 0;
    iRet = sigsetjmp(sigBuf,1);
    if (0 == iRet)
    {
        FunA();
    }
    else if (iRet != 0)
    {
        printf("program close!\n");
    }
    return 0;
}

源文件B:call.c

#include
#include
extern sigjmp_buf sigBuf;
void call()
{
   printf("Enter call!\n");
   siglongjmp(sigBuf,1);
   printf("Exit call!\n");
}
[root@localhost sigsetjmp]#


编译:
  [root@localhost sigsetjmp]# gcc -o sigsetjmp sigsetjmp.c call.c
  [root@localhost sigsetjmp]#

运行:
  [root@localhost sigsetjmp]# ./sigsetjmp
   Enter FunA!
   Enter call!
   program close!
  [root@localhost sigsetjmp]#

但如果把call()改为
void call()
{
   printf("Enter call!\n");
   printf("Exit call!\n");
}

编译、运行结果如下:
[root@localhost sigsetjmp]# ./sigsetjmp
 Enter FunA!
 Enter call!
 Exit call!
 Exit FunA!
[root@localhost sigsetjmp]#

  上面的结果说明在不同源文件中使用sigsetjmp & siglongjmp,明显的改变了程序的顺序执行流程,能达到类似goto的效果。
  另外:
 
  对于man手册中这句我没有理解:
    If savesigs is non-zero, the set of blocked signals is saved in env and will be restored if a siglongjmp(3) is later performed with this env.

    如查savesigs非0,那个阻塞信号将会保存在env中并于siglongjmp调用时恢复。

    我用sigsetjmp_signal.c试了一下,将SIGINT的信号阻塞,但调用siglongjmp并没用调用SIGINT的处理函数。有知道的朋友希望回复我一下,十分感谢。

源文件:sigsetjmp_signal.c

#include
#include
#include
sigjmp_buf sigBuf;
void FunB()
{
    printf("Enter FunB!\n");
    printf("Exit FunB!\n");
}
void FunA()
{
    printf("Enter FunA!\n");
    call();
    printf("Exit FunA!\n");
}

int main(int argc,char *argv[])
{
    int iRet = 0;
    struct sigaction act;
    sigset_t stSig;
   
    sigemptyset(&stSig);
    sigaddset(&stSig, SIGINT);
    sigprocmask(SIG_BLOCK, &stSig, NULL);/*阻塞信号SIGINT*/

    act.sa_handler = FunB;/*指定SIGINT信号响应函数*/
    act.sa_flags = SA_INTERRUPT;
    sigemptyset(&act.sa_mask);
    if (sigaction(SIGINT,&act,NULL) != 0)
    {
        perror("sigaction");
    }
   
    iRet = sigsetjmp(sigBuf,1);
    if (0 == iRet)
    {
        kill(getpid(),SIGINT);
        FunA();
    }
    else if (iRet != 0)
    {
        printf("program close!\n");
    }
    return 0;
}

上传文件为例子中使用源码,本人水平有限,发文目的纯属交流,希望高手勿拍砖。

阅读(2212) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:socket编程中recvfrom的非阻塞设置方法

给主人留下些什么吧!~~