美文网首页
信号函数编写研究

信号函数编写研究

作者: 五菱老司机 | 来源:发表于2017-12-06 09:56 被阅读11次

APUE读书笔记

ToDoList

  • [ ] sleep初级实现 2017年12月6日 10:41:30
  • [ ] sleep进阶实现
  • [ ] sleep高阶实现
  • [ ] sleep内核具体实现

第十章

项目 时间 文档版本 作者 备注
读书笔记 2017/12/06 初稿 shiyanhk@gmail.com 添加第十章内容

[TOC]


1 编写目的

之前对singnal信号理解一知半解,就这篇文章想通过我的描述来把signal这一章节,深入浅出的讲解出来.

不妨我们就从apue书中具体用例展开我们需要的描述,虽然片面,后续仍会有修改和添加,

2 sleep函数基于信号实现,循序渐进的几个用例

2.1.1 sleep初级实现

2.1.2 代码

static void sig_alrm(int signo){
    /* nothing to do, just return to wake up the pause */
}

unsigned int sleep1(unsigned int nsecs){
    if (signal(SIGALRM, sig_alrm) == SIG_ERR)
        return(nsecs);
    alarm(nsecs);       /* start the timer */
    pause();            /* next caught signal wakes us up */
    return(alarm(0));   /* turn off timer, return unslept time */
}

2.1.2问题
  • 1.如果调用者已设置了闹钟,则它被sleep1函数中的第一次alarm调用擦去
  • 2.该程序中修改了对SIGALRM的配置。
  • 3.在调用 alarm和pause之间有一个竞态条件。

2.1.3解决办法

  • 1.利用alarm返回值确定上次信号状态
  • 2.利用signal返回值确定signal函数原始回调操作
  • 3.利用setjmp和longjmp修改

2.1.4 详细分析

问题 1
利用alarm返回值记录 剩余时钟

可用下列方法更正这一点:检查第一次调用alarm的返回值,如其小于本次调用 alarm的参数值,则只应等到该前次设置的闹钟时间超时。如果前次设置闹钟时间的超时时刻后于本次设置值,则在sleep1函数返回之前,再次设置闹钟时间,使其在预定时间再发生超时。

问题1代码实现


问题 2
该程序中修改了对SIGALRM的配置。

在一个繁忙的系统中,可能 a l a r m在调用 p a u s e之前超时,并调用了信号处理程序。如果发生了这种情况,则在调用 p a u s e后,如果没有 捕捉到其他信号,则调用者将永远被挂起.

没有对原信号处理程序做保存 修改信号掩码 对未决信号 做特殊处理=
可用下列方法更正这一点:检查第一次调用 alarm的返回值,如其小于本次调用 alarm的参数值,则只应等到该前次设置的闹钟时间超时。如果前次设置闹钟时间的超时时刻后于本次设置值,则在sleep1函数返回之前,再次设置闹钟时间,使其在预定时间再发生超时。

问题 2代码实现



问题 3
**在调用 alarm和pause之间有一个竞态条件。 **

在一个繁忙的系统中,可能 a l a r m在调用 p a u s e之前超时,并调用了信号处理程序。如果发生了这种情况,则在调用 p a u s e后,如果没有 捕捉到其他信号,则调用者将永远被挂起

** 利用setjmp和longjmp函数切换上下文**
SVR2中的sleep实现使用了setjmp和longjmp (见7 . 1 0节)以避免问题( 3 )中所说明的竞态条件。
此函数的一个简化版本,称为 s l e e p 2,示于程序 1 0 - 5中(为了缩短实例长度,程序中没有处理
上面所说的问题( 1 )和( 2 )

问题 3代码实现

这部分比较复杂,我们放到下一章节单独来讲

10.8

sleep进阶实现

代码

static jmp_buf  env_alrm;

static void
sig_alrm(int signo)
{
    printf("时钟信号来了,我进入了信号回调函数 sig_alrm\n");
    printf("我尝试了longjmp(env_alrm, 1);再次跳转到主调函数 \n");
    longjmp(env_alrm, 1);// 通常第二个参数都默认写成1
    printf("跳出了 sig_alrm\n");//此行代码无效
}




// 避免了pause函数和alarm韩寒苏竞争
unsigned int
sleep2(unsigned int nsecs)
{
    if (signal(SIGALRM, sig_alrm) == SIG_ERR)  
        return(nsecs);
    if (setjmp(env_alrm) == 0) { // 设置一个longjmp的标签  返回值为0表示成功完成了设置
       // 我设置了一个 
        printf("我成功的设置了 setjmp(env_alrm) \n");
        printf("我设置了一个 %d 秒的闹钟信号\n",nsecs);
        alarm(nsecs);       /* start the timer */   // 来个闹钟实时  如果时钟信号来了  那么代码跳到25行重新来过 避免了alarm先调用 后面pause没法结束
        printf("成功定时向本进程发送一个时钟信号\n");
        printf("在此pause等待时钟信号.......\n\n\n");
        pause();            /* next caught signal wakes us up */
    }
    return(alarm(0));       /* turn off timer, return unslept time */
}


st=>start: Start 
io=>inputoutput: verification 
op=>operation: Your Operation 
cond=>condition: Yes or No? 
e=>end

st->io->op->cond 
cond(yes)->e 
cond(no)->io 

相关文章

  • 信号函数编写研究

    APUE读书笔记 ToDoList [ ] sleep初级实现 2017年12月6日 10:41:30 [ ] ...

  • 无标题文章

    [TOC] ### 10.7 信号函数定义中应该注意的问题 #### 编写信号处理程序常见问题剖析 用例代码 ``...

  • 第4章、服务器程序框架初步

    第一节 服务器程序目录规划、makefile编写1、信号高级认识范例a、信号处理函数执行过程中,不会执行主程序b、...

  • C笔试题

    mvcmodelviewcontorller工厂模式观察者模式代理模式 信号与槽第一种:自己编写槽函数使用conn...

  • linux-10 -信号(2)+IPC

    信号:信号的发送函数/信号集和信号屏蔽/介绍一个sigaction()/信号应用的相关函数:sleep(),usl...

  • day8-作业

    编写⼀个函数,求1+2+3+...+N程序: 结果: 编写⼀个函数,求多个数中的最⼤值程序: 结果: 编写⼀个函数...

  • C++作业-导数

    一元连续函数求导。1)编写一个函数用于计算2)编写一个函数用于计算3)编写一个函数用于计算;(提示:使用exp函数...

  • effive c++

    编写函数

  • day8-作业

    编写⼀个函数,求1+2+3+...+N 编写⼀个函数,求多个数中的最⼤值 编写⼀个函数,实现摇⾊⼦的功能,打印n个...

  • Day-作业

    编写⼀个函数,求1+2+3+...+N 编写⼀个函数,求多个数中的最⼤值 编写⼀个函数,实现摇⾊⼦的功能,打印n个...

网友评论

      本文标题:信号函数编写研究

      本文链接:https://www.haomeiwen.com/subject/jskkixtx.html