http://blog.csdn.net/muge0913/article/details/7331129

要对一个信号进行处理,就需要给出此信号发生时系统所调用的处理函数。可以对一个特定的信号(除去SIGKILL和SIGSTOP信号)注册相应的处理函数。注册某个信号的处理函数后,当进程接收到此信号时,无论进程处于何种状态,就会停下当前的任务去执行此信号的处理函数。

1、注册信号函数。

  1. #include<signal.h>
  2. void(*signal(int signumber,void ((*func)(int))(int)

signumber表示信号处理函数对应的信号。func是一个函数指针。此函数有一整型参数,并返回void型。其实func还可以取其他定值如:SIG_IGN,SIG_DFL.

SIG_IGN表示:忽略signumber所指出的信号。SIG_DFL表示表示调用系统默认的处理函数。signal函数的返回值类型同参数func,是一个指向某个返回值为空并带有一个整型参数的函数指针。其正确返回值应为上次该信号的处理函数。错误返回SIG_ERR

signal示例如下:

  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <stdlib.h>
  4. #include <signal.h>
  5. void func(int sig)
  6. {
  7. printf("I get asignal!\n");
  8. }
  9. int main()
  10. {    charbuffer[100];
  11. if(signal(SIGINT, func) == SIG_ERR)
  12. {
  13. printf("signalerror exit now\n");
  14. exit(0);
  15. }
  16. printf("pid:%ld\n",(long)getpid());
  17. for(;;)
  18. {
  19. fgets(buffer,sizeof(buffer),stdin);
  20. printf("bufferis:%s\n",buffer);
  21. }
  22. return 0;
  23. }

通常情况下一个用户进程需要处理多个信号。可以在一个程序中注册多个信号处理函数。一个信号可以对应一个处理函数,同时多个信号可以对应一个处理函数。

对于SIGINT信号 我们可以用ctrl+c或ctrl+z来中断进程,来执行SIGINT注册的函数。

2、 高级信号处理。

在linux系统提供了一个功能更强的系统调用。

  1. #include <signal.h>
  2. int sigaction(int signumbet,const structsigaction *act,struct sigaction *oldact)

此函数除能注册信号函数外还提供了更加详细的信息,确切了解进程接收到信号,发生的具体细节。

struct sigaction的定义如下:在linux2.6.39/include/asm-generic/signal.h中实现

  1. struct sigaction
  2. {
  3. void(*sa_handler)(int);
  4. void(*sa_sigaction)(int,siginfo_t *,void *);
  5. sigset_tsa_mask;
  6. intsa_flags;
  7. }

siginfo_t在linux2.6.39/include/asm-generic/siginfo.h中实现:

sa_flags的取值如下表,取0表示选用所有默认选项。

SA_NOCLDSTOP:用于表示信号SIGCHLD,当子进程被中断时,不产生此信号,当且仅当子进程结束时产生此信号。

SA_NOCLDWATI:当信号为SIGCHLD,时可避免子进程僵死。

SA_NODEFER:当信号处理函数正在进行时,不堵塞对于信号处理函数自身信号功能。

SA_NOMASK:同SA_NODEFER

SA_ONESHOT:当用户注册的信号处理函数被执行过一次后,该信号的处理函数被设为系统默认的处理函数。

SA_RESETHAND:同SA_ONESHOT

SA_RESTART:是本来不能重新于运行的系统调用自动重新运行。

SA_SIGINFO:表明信号处理函数是由SA_SIGACTION指定的,而不是由SA_HANDLER指定的,它将显示更多的信号处理函数信息。

其实sinaction完全可以替换signal函数

  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <stdlib.h>
  4. #include <signal.h>
  5. void func(int sig)
  6. {
  7. printf("I get a signal!\n");
  8. }
  9. int main()
  10. {   char buffer[100];
  11. struct sigaction act;
  12. act.sa_handler=func;
  13. sigemptyset(&act.sa_mask);
  14. act.sa_flags = 0;
  15. if(sigaction(SIGINT,&act, NULL) == -1)
  16. {
  17. printf("sigaction error exit now\n");
  18. exit(0);
  19. }
  20. printf("pid:%ld\n",(long)getpid());
  21. for(;;)
  22. {
  23. fgets(buffer,sizeof(buffer),stdin);
  24. printf("buffer is:%s\n",buffer);
  25. }
  26. return 0;
  27. }

linux c 之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. Linux信号(signal) 机制分析

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

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

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

  5. Linux信号(signal) 机制分析-(转自h13)

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

  6. signal() 和 sigaction()

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

  7. Linux Kernel: buffers和cached的区别

    The page cache caches pages of files to optimize file I/O. The buffer cache caches disk blocks to op ...

  8. Linux read/write fread/fwrite两者区别

    Linux read/write fread/fwrite两者区别 1,fread是带缓冲的,read不带缓冲. 2,fopen是标准c里定义的,open是POSIX中定义的. 3,fread可以读一 ...

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

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

随机推荐

  1. SQL基础--&gt; 约束(CONSTRAINT)

    --============================= --SQL基础--> 约束(CONSTRAINT) --============================= 一.几类数据完 ...

  2. Android Studio常用插件

    ButterKnife 这个开源库可以让我们从大量的findViewById()和setonclicktListener()解放出来,其对性能的影响微乎其微(查看过Butter Knife的源码,其自 ...

  3. 配置PPTP服务器

    1.验证内核是否加载了MPPE模块: modprobe ppp-compress-18 && echo MPPE is ok 2.安装所需的软件包: yum -y install pp ...

  4. RHEL7查看网卡配置命令ip addr show

    Validating Network Address Configuration To verify the configuration of the network address, you nee ...

  5. HDU 1199 - Color the Ball 离散化

    [题意]现在有几个球排成一排,编号从1开始,开始时所有球为黑色,现在有n(<=2000)次操作,每次操作将l[i]至r[i](均在int范围)的球凃成颜色c[i](黑色'b'或白色'w'),然后 ...

  6. MSSQL查询所有数据库表,指定数据库的字段、索引

    --查询所有数据库USE mastergoselect [name] from [sysdatabases] order by [name] --查询其中一个数据库test,就可以得到这个数据库中的所 ...

  7. 汇编笔记之 ret 、retf和call

    作用: ret  将 栈顶数据出栈到IP retf 将 栈顶数据出栈到IP ,然后再次将栈顶数据出栈到CS 这样一来,可以使程序跳转到已经定义好了的代码段去执行. call 语法 call s0 (如 ...

  8. oracle查询blob类型

    下午要查询一个数据,要求是从 表t_report 中查找出 mainbody字段中包含“hibernate”字符串的所有信息.而mainbody字段是blob类型.百度后终于找到答案: DBMS_LO ...

  9. java事件处理

    1.ActionEven事件 文本框,按钮,菜单项,密码框,单选按钮都可以出发ActionEvent事件 使用 addActionListener(ActionListener listen1) 来注 ...

  10. 利用 Makefile 写的小程序

    1.建立一个工程 2.写一个进度条的程序(原理就是在同一位置重复打印某一个字符(变化),达到动态显示的效果) 所以说我们这里只用回车'\r',覆盖这一行以前的输出,重新向缓冲区写数据刷新缓冲区,就能达 ...