测试证明代码:

#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include "apue.h" static void sig_alrm(int signo)
{
/* nothing to do, just returning wakes up sigsuspend */
} static void sig_usr1(int signo)
{ } //static void sig_alrm_test(int signo)
//{
// err_msg("left an alrm");
//} unsigned int sleep(unsigned int seconds)
{
struct sigaction newact, oldact;
sigset_t newmask, oldmask, suspmask;
unsigned int unslept; timespec ts; // ++
ts.tv_sec = ; // ++
ts.tv_nsec = ; // ++ /* set our handler, save previous information */
newact.sa_handler = sig_alrm;
sigemptyset(&newact.sa_mask);
newact.sa_flags = ;
sigaction(SIGALRM, &newact, &oldact); /* block SIGALRM and save current signal mask */
sigemptyset(&newmask);
sigaddset(&newmask, SIGALRM);
sigprocmask(SIG_BLOCK, &newmask, &oldmask); alarm(seconds);
suspmask = oldmask; /* make sure SIGALRM isn't block */
sigdelset(&suspmask, SIGALRM); /* wait for any signal to be caught */
sigsuspend(&suspmask); nanosleep(&ts, NULL); // ++ /* some signal has been caught, SIGALRM is now blocked */
unslept = alarm(); /* reset previous action */
sigaction(SIGALRM, &oldact, NULL); /* reset signal mask, which unblocks SIGALRM */
sigprocmask(SIG_SETMASK, &oldmask, NULL);
return unslept;
} int main(int argc, char *argv[])
{
struct sigaction useract;
struct sigaction alrmact; useract.sa_handler = sig_usr1;
sigemptyset(&useract.sa_mask);
useract.sa_flags = ;
if (sigaction(SIGUSR1, &useract, NULL) < )
err_sys("SIG SUR1 error"); // alrmact.sa_handler = sig_alrm_test;
// sigemptyset(&alrmact.sa_mask);
// alrmact.sa_flags = 0;
// if (sigaction(SIGALRM, &alrmact, NULL) < 0)
// err_sys("SIG ALRM error"); sleep(); return ;
}

操作说明,这里我给出我和作者交流时的说明,所以用的是英文,不过我英文水平有限,希望谅解:

I should give you my manipulation. You should send a SIGUSR1 to the process in less than 20 seconds. So that when alarm(0) tries to cancel the alarm, it was not expired. You see, I didn't send the process SIGALARM, but the SIGALARM handler was fired.

下面是运行时候的结果(为了让作者可以看清楚,使用的是英文):

下面是作者的回复(中间有一些曲折,给出最后的部分回复内容):

Yes, there is a very small window where if the sigsuspend() is interrupted by a different signal and the SIGALRM is posted before calling alarm(0) to cancel it, that the process will be terminated if the default disposition of SIGALRM is in effect.  You have artificially widened that window by adding the call to nanosleep().

sleep function error ("Advanced Programming in the UNIX Environment" Third Edition No.374)的更多相关文章

  1. Atlassian JavaScript load error(配置Atlassian的时候报无法加载script文件)

    等我弄好的时候,发现报错的图已经成为历史了,所以就没有截图了. Atlassian JavaScript load error We tried to load scripts but somethi ...

  2. javaScript设计模式之面向对象编程(object-oriented programming,OOP)(一)

    面试的时候,总会被问到,你对javascript面向对象的理解? 面向对象编程(object-oriented programming,OOP)是一种程序设计范型.它讲对象作为程序的设计基本单元,讲程 ...

  3. Sth about 函数式编程(Functional Programming)

    今天开会提到了函数式编程,针对不同类型的百年城方式,查阅了一部分资料,展示如下: 编程语言一直到近代,从汇编到C到Java,都是站在计算机的角度,考虑CPU的运行模式和运行效率,以求通过设计一个高效的 ...

  4. 编程范式 --- 函数式编程(Funtional Programming,简称FP)

    函数式编程(Funtional Programming,简称FP)是一种编程范式,也就是如何编写程序的方法论 主要思想:把计算过程尽量分解成一系列可复用函数的调用 主要特征:函数是"第一等公 ...

  5. mysql 链接失败(ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES))

    mysql链接失败(ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)) 修改: # ...

  6. Sql server2012连接Sql server 2008时出现的问题:已成功与服务器建立连接,但在登陆过程中发生错误。(provider:SSL Provider,error:0-接收到的消息异常,或格式不正确。)

    以前连接是正常的,就这两天连不上了.(没有耐心的直接看末尾解决办法) 错误消息如下: 1.尝试读取或写入受保护的内存.这通常指示其他内存已损坏.(System.Data) 2.已成功与服务器建立连接, ...

  7. function adapter(函数适配器)和迭代器适配器

    所谓function adapter(函数适配器)是指能够将不同的函数对象(或是和某值或某寻常函数)结合起来的东西,它自身也是个函数对象. 迭代器适配器  运用STL中的迭代器适配器,可以使得算法能够 ...

  8. ALV详解:Function ALV(二)

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  9. ALV详解:Function ALV(一)

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

随机推荐

  1. CentOS7安装PostgreSQL10,pgadmin4

    ======PostgreSQL10 CentOS7=================FYI:https://tecadmin.net/install-postgresql-server-centos ...

  2. JAVA的初始化顺序:

    JAVA的初始化顺序: 父类的静态成员初始化>父类的静态代码块>子类的静态成员初始化>子类的静态代码块>父类的代码块>父类的构造方法>子类的代码块>子类的构造 ...

  3. oracle服务器重启后无法进入系统,登录系统时提示model is unknow

    这个是因为安装oracle时,修改了一些系统参数,导致开机异常 在选择系统列表那里直接按e,进入系统开机配置 大概在倒数第二行,也就是有utf8那行,添加init=/bin/sh 然后ctrl+x重启 ...

  4. windows知识

    文章目录 系统 修改远程桌面的端口号 IE选项中reset web setting不可用(灰色)的解决办法 重装系统后,修改默认程序安装目录.我的文档.桌面 路径 Keep network addre ...

  5. 数学沉思录:古今数学思想的发展与演变 (Mario Livio 著)

    第1章 神秘的数学 (已看) 发现还是发明 第2章 神秘学:命理学家和哲学家 (已看) 毕达哥拉斯 进入柏拉图的洞穴 第3章 魔法师:大师和异端 (已看) 给我一个支点:我将撬起地球 阿基米德重写稿 ...

  6. 枚举 Java Enumeration接口

    Enumation 定义了一些方法,通过这些方法可以枚举对象集合中的元素 如: boolean hasMoreElements() 测试此枚举是否包含更多的元素 object nextElement( ...

  7. JFrame添加组件

    jframe.add(button) 与 jframe.getContentPane().add(button) 结果是一样的, 都是将组件添加到jframe自带的容器ContentPane中.

  8. hadoop不同版本有哪些

    一.Hadoop是什么? 首次听到hadoop这次单词,相信很多人跟我当时是一样,不免心中画上一个大大的问号——这是什么东西?Hadoop是什么?百度百科的解释是:Hadoop是一个由Apache基金 ...

  9. MySQL程序之mysqldump详解

    mysqldump命令详解 mysqldump是mysql用于转存储数据库的实用程序.它主要产生一个SQL脚本,其中包含从头重新创建数据库所必需的命令CREATE TABLE INSERT等 用法: ...

  10. 通过Hibernate API编写访问数据库的代码

    private Configuration config;// 1.声明私有配置对象类private ServiceRegistry serviceRegistry;// 2.声明私有服务注册对象类p ...