1:signal 函数

  原型: sighandler_t signal(int signum, sighandler_t handler)      typedef void (*sighandler_t)(int);

  描述:signal函数用来在进程中指定当一个信号到达进程后该做什么处理,主要的两种方式有忽略某些信号,(监听到SIGTERM/SIGINT)退出前的打扫工作。信号处理函数的handler有两个默认值,分别是SIG_IGNSIG_DFL,表示忽略和默认行为。而且signal函数是阻塞的,比如当进程正在执行SIGUSR1信号的处理函数,此时又来一个SIGUSR1信号,signal会等到当前信号处理函数处理完后才继续处理后来的SIGUSR1,不管后来的多少个SIGUSR1信号,统一看做一个来处理。还有SIGKILLSIGSTOP这两个信号是signal函数捕捉不到的。

  注意:signal函数的行为与linux的版本有关(因为signal属于系统调用),所以移植性不好,可用sigaction函数来替代(sigaction是标准POSIX函数),而且sigaction还扩展了signal函数的功能。

2:sigaction函数

  原型:int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

  参数:

    signum:信号值

    act:信号的处理参数

    oldact:保存信号上次安装时的处理参数(备份的作用)

  返回值:0(success),-1(error)

struct sigaction {
void (*sa_handler)(int); //信号处理函数
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask; //信号屏蔽集
int sa_flags;
void (*sa_restorer)(void);// 已废弃
};

  要点:

    信号阻塞:同signal函数类似,当正处于某个信号的处理函数中时,这个信号再次到达会被阻塞,待信号处理函数完成之后再处理。

      sa_mask :信号屏蔽集,所谓屏蔽并不是忽略,屏蔽的时间段是在信号处理函数执行期间,一旦处理函数执行完毕将会重新唤醒此信号。

    sa_flags :SA_RESTART:表示如果一个信号到来时进程正在执行某个系统调用(read/write等),执行完信号处理函数后返回系统调用,此系统调用会重新调用而不会出错。

实例1(sa_mask的使用):

#include <errno.h>
#include <string.h> static void signal_handler(int sig)
{
printf("Got SIGUSR1\n");
printf("Processing SIGUSR1...\n");
sleep();
printf("sleep over\n");
} int main(int argc, char** argv)
{
char buf[];
int n = ;
printf("PID:%d\n", getpid());
struct sigaction act, oldact;
act.sa_handler = signal_handler;
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask, SIGINT);//把SIGINT信号加入屏蔽集
//act.sa_flags = SA_RESTART;
if(sigaction(SIGUSR1, &act, &oldact) < )
{
perror("sigaction error");
return -;
}
/*
for(;;){
memset(buf, 0, 20);
if((n = read(0, buf, 20)) < 0){
perror("read:");
}
else{
buf[n] = '\0';
printf("%d type got, string:%s\n", n, buf);
}
}
*/
sleep();
return ;
}

结果:

实例2(sa_flags=SA_RESTART):

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <string.h> static void signal_handler(int sig)
{
printf("Got SIGUSR1\n");
printf("Processing SIGUSR1...\n");
sleep();
printf("sleep over\n");
} int main(int argc, char** argv)
{
char buf[];
int n = ;
printf("PID:%d\n", getpid());
struct sigaction act, oldact;
act.sa_handler = signal_handler;
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask, SIGINT);
act.sa_flags = SA_RESTART;//设置SA_RESTART flag
if(sigaction(SIGUSR1, &act, &oldact) < )
{
perror("sigaction error");
return -;
} memset(buf, , );
if((n = read(STDIN_FILENO, buf, )) < ){//行缓冲阻塞
perror("read:");
}
else{
buf[n] = '\0';
printf("%d type got, string:%s\n", n, buf);
} return ;
}

结果:

将 act.sa_flags = SA_RESTART; 这行代码屏蔽之后:

可以看到,SA_RESTART参数确实保证了被中断的系统调用在中断之后恢复之前的状态继续执行(系统调用中断出错应该报告Interrupted system call,不知我这里为何是core dumped?)。

signal和sigaction 分析的更多相关文章

  1. Linux 信号:signal 与 sigaction

    0.Linux下查看支持的信号列表: france@Ubuntux64:~$ kill -l ) SIGHUP ) SIGINT ) SIGQUIT ) SIGILL ) SIGTRAP ) SIGA ...

  2. Linux进程间通信(一): 信号 signal()、sigaction()

    一.什么是信号 用过Windows的我们都知道,当我们无法正常结束一个程序时,可以用任务管理器强制结束这个进程,但这其实是怎么实现的呢?同样的功能在Linux上是通过生成信号和捕获信号来实现的,运行中 ...

  3. signal() 和 sigaction()

    [摘自<Linux/Unix系统编程手册>] Unix系统提供了两种方式来改变信号处置:signal() 和 sigaction(). signal() 的行为在不同Unix实现间存在差异 ...

  4. 信号处理signal、sigaction、pause、信号嵌套处理、不可重入函数

    信号的捕捉和处理 主要由signal和sigaction函数来完成.还有一个函数pause,它可用来响应任何信号,不过不做任何处理. 1.signal函数 typedef void (*sighand ...

  5. APUE学习笔记——10信号——信号接口函数 signal 和 sigaction

    signal函数     signal函数是早起Unix系统的信号接口,早期系统中提供不可靠的信号机制.在后来的分支中,部分系统使用原来的不可靠机制定义signal函数,如 Solaris 10 .而 ...

  6. linux c 之signal 和sigaction区别

    http://blog.csdn.net/muge0913/article/details/7331129 要对一个信号进行处理,就需要给出此信号发生时系统所调用的处理函数.可以对一个特定的信号(除去 ...

  7. linux 信号signal和sigaction理解

    今天看到unp时发现之前对signal到理解实在浅显,今天拿来单独学习讨论下. signal,此函数相对简单一些,给定一个信号,给出信号处理函数则可,当然,函数简单,其功能也相对简单许多,简单给出个函 ...

  8. Linux信号(signal) 机制分析

    Linux信号(signal) 机制分析 [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核 ...

  9. Linux信号(signal) 机制分析(转)

    [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核对于信号的处理流程包括信号的触发/注册/执 ...

随机推荐

  1. We are writing to let you know we have removed your selling privileges

     Hello, We are writing to let you know we have removed your selling privileges, canceled your listin ...

  2. 欢迎来怼——第四次Scrum会议

    一.小组信息 队名:欢迎来怼小组成员队长:田继平成员:李圆圆,葛美义,王伟东,姜珊,邵朔,冉华小组照片 二.开会信息 时间:2017/10/16 17:15~17:40,总计25min.地点:东北师范 ...

  3. 《JavaScript》页面跳转

    window.location.href: <i onclick="window.location.href = '/Form/Form_Write/Index?viewname=Fo ...

  4. OA--对于每个form表单(<s:iterator>生成)的处理

    由于是后台传过来的,我们不知道form 有几个 也不能指定form的id和name,(其实也可以就是可能会冲突我们还是用下面讲的方法把) 之前有想过 对于每个form 里面都有一些参数,举个例子 项目 ...

  5. lilntcode-508-摆动排序

    508-摆动排序 给你一个没有排序的数组,请将原数组就地重新排列满足如下性质 nums[0] <= nums[1] >= nums[2] <= nums[3].... 注意事项 请就 ...

  6. 第10章 vim程序编辑器

    vi和vim vim是vi的升级版,支持vi的所有指令 vi的使用 vi分为三种模式:一般模式.编辑模式.命令行模式 一般模式 以vi打开一个文件就直接进入一般模式了,这个模式下可以使用上下左右按键来 ...

  7. weblogic下JNDI及JDBC连接测试(weblogic环境)

    JNDI的专业解释,大家自行去网络搜索吧,这里就不啰嗦了. 单纯从使用角度看,可以简称把它看成一个key-value的“哈希资源”容器.给定一个string类型的key,可以把任何类型的value,放 ...

  8. 【beta】Scrum站立会议第3次....11.6

    小组名称:nice! 组长:李权 成员:于淼  刘芳芳韩媛媛 宫丽君 项目内容:约跑app(约吧) 时间:2016.11.6  12:00——12:30 地点:传媒西楼220室 本次对beta阶段的需 ...

  9. Kettle 使用Json输入

    import java.math.BigDecimal; private static final String JD="jd"; private static final Str ...

  10. script 执行的三种方式

    <script>: 脚本的获取和执行是同步的.此过程中页面被阻塞,停止解析. <script defer = "defer">:脚本的获取是异步的,执行是同 ...