c语言sigaction,c语言信号处理sigaction[通俗易懂]

c语言sigaction,c语言信号处理sigaction[通俗易懂]c语言信号处理sigaction(2011-04-1823:45:19)标签:c语言信号处理sigactionsighupit分类:c信号安装函数sigaction(intsignum,conststructsigaction*act,structsigaction*oldact)的第二个参数是一个指向sigaction结构的指针(结构体名称与函数名一样,千万别弄混淆了)。在结构sig…

大家好,又见面了,我是你们的朋友全栈君。

c语言信号处理sigaction

a4c26d1e5885305701be709a3d33442f.png

(2011-04-18 23:45:19)

标签:

c语言

信号处理

sigaction

sighup

it

分类:

c

信号安装函数sigaction(int signum,const struct sigaction *act,struct sigaction

*oldact)的第二个参数是一个指向sigaction结构的指针(结构体名称与函数名一样,千万别弄混淆了)。在结构sigaction的实例中,指定了对特定信号的处理,信号所传递的信息,信号处理函数执行过程中应屏蔽掉哪些函数等。当然,此指针也可以为NULL,进程会以默认方式处理信号。以下就简单介绍一下sigaction结构以及一般的用法。

对于内核头文件而言,struct sigaction

结构体定义在kernel/include/asm/signal.h,此头文件又被kernel/include/linux/signal.h包含。

对于用户空间的头文件而言,struct sigaction定义在

/usr/include/bits/sigaction.h,此头文件又被/usr/include/signal.h包含,所以应用程序中如果用到此结构,只要#include

即可。注意内核中的定义和应用程序中的定义是不一样的,内核空间的sigaction结构只支持函数类型为

__sighandler_t的信号处理函数,不能处理信号传递的额外信息。具体定义如下:

……

typedef void (*__sighandler_t)(int);

……

#ifdef __KERNEL__

struct old_sigaction {

__sighandler_t sa_handler;

old_sigset_t sa_mask;

unsigned long sa_flags;

void (*sa_restorer)(void);

};

struct sigaction {

__sighandler_t sa_handler;

unsigned long sa_flags;

void (*sa_restorer)(void);

sigset_t sa_mask;

};

struct k_sigaction {

struct sigaction sa;

};

#else

struct sigaction {

union {

__sighandler_t _sa_handler;

void (*_sa_sigaction)(int, struct siginfo *, void *);

} _u;

sigset_t sa_mask;

unsigned long sa_flags;

void (*sa_restorer)(void);

};

#define sa_handler _u._sa_handler

#define sa_sigaction _u._sa_sigaction

#endif

sa_handler的原型是一个参数为int,返回类型为void的函数指针。参数即为信号值,所以信号不能传递除信号值之外的任何信息;

sa_sigaction 的原型是一个带三个参数,类型分别为int,struct siginfo *,void

*,返回类型为void的函数指针。第一个参数为信号值;第二个参数是一个指向struct

siginfo结构的指针,此结构中包含信号携带的数据值;第三个参数没有使用。

sa_mask指定在信号处理程序执行过程中,哪些信号应当被阻塞。默认当前信号本身被阻塞。

sa_flags

包含了许多标志位,比较重要的一个是SA_SIGINFO,当设定了该标志位时,表示信号附带的参数可以传递到信号处理函数中。即使

sa_sigaction指定信号处理函数,如果不设置SA_SIGINFO,信号处理函数同样不能得到信号传递过来的数据,在信号处理函数中对这些信息的访问都将导致段错误。

sa_restorer已过时,POSIX不支持它,不应再使用。

因此,当你的信号需要接收附加信息的时候,你必须给sa_sigaction赋信号处理函数指针,同时还要给sa_flags赋SA_SIGINFO,类似下面的代码:

#include

……

void sig_handler_with_arg(int sig,siginfo_t *sig_info,void

*unused){……}

int main(int argc,char **argv)

{

struct sigaction sig_act;

……

sigemptyset(&sig_act.sa_mask);

sig_act.sa_sigaction=sig_handler_with_arg;

sig_act.sa_flags=SA_SIGINFO;

……

}

如果你的应用程序只需要接收信号,而不需要接收额外信息,那你需要的设置的是sa_handler,而不是sa_sigaction,你的程序可能类似下面的代码:

#include

……

void sig_handler(int sig){……}

int main(int argc,char **argv)

{

struct sigaction sig_act;

……

sigemptyset(&sig_act.sa_mask);

sig_act.sa_handler=sig_handler;

sig_act.sa_flags=0;

……

}

如果需要更详细说明,请参阅sigaction的man手册。

补充:

简而言之就是:

//自定义退出函数

sigact.sa_handler = mysighandler;

sigemptyset(&sigact.sa_mask);

sigact.sa_flags = 0;

sigaction(SIGINT, &sigact, NULL);

sigaction(SIGTERM, &sigact, NULL);

sigaction(SIGQUIT, &sigact, NULL);

或者利用signal函数进行信号捕捉:

void (*signal(int signo, void (*handler)(int)))(int);

当signal到来时,程序运行某函数,函数由你自己指定。

附带各种信号定义:

在终端使用kill -l 命令可以显示所有的信号。

$kill -l

1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL

5) SIGTRAP 6) SIGABRT 7) SIGBUS

a4c26d1e5885305701be709a3d33442f.png

SIGFPE

9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2

13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT

17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP

21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU

25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH

29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN

35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4

39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8

43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46)

SIGRTMIN+12

47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50)

SIGRTMAX-14

51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54)

SIGRTMAX-10

55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6

59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2

63) SIGRTMAX-1 64) SIGRTMAX

其中前面31个信号为不可靠信号(非实时的,可能会出现信号的丢失),后面的信号为可靠信号(实时的real_time,对信号

排队,不会丢失)。

1) SIGHUP (挂起) 当运行进程的用户注销时通知该进程,使进程终止

2) SIGINT (中断) 当用户按下时,通知前台进程组终止进程

3) SIGQUIT (退出) 用户按下或时通知进程,使进程终止

4) SIGILL (非法指令) 执行了非法指令,如可执行文件本身出现错误、试图执行数据段、堆栈溢出

5) SIGTRAP 由断点指令或其它trap指令产生. 由debugger使用

6) SIGABRT (异常中止) 调用abort函数生成的信号

7) SIGBUS 非法地址, 包括内存地址对齐(alignment)出错. eg: 访问一个四个字长的整数,

但其地址不是4的倍数.

8) SIGFPE (算术异常) 发生致命算术运算错误,包括浮点运算错误、溢出及除数为0.

9) SIGKILL (确认杀死) 当用户通过kill -9命令向进程发送信号时,可靠的终止进程

10) SIGUSR1 用户使用

11) SIGSEGV (段越界) 当进程尝试访问不属于自己的内存空间导致内存错误时,终止进程

12) SIGUSR2 用户使用

13) SIGPIPE 写至无读进程的管道, 或者Socket通信SOCT_STREAM的读进程已经终止,而再写入。

14) SIGALRM (超时) alarm函数使用该信号,时钟定时器超时响应

15) SIGTERM (软中断) 使用不带参数的kill命令时终止进程

17) SIGCHLD (子进程结束) 当子进程终止时通知父进程

18) SIGCONT (暂停进程继续) 让一个停止(stopped)的进程继续执行. 本信号不能被阻塞.

19) SIGSTOP (停止) 作业控制信号,暂停停止(stopped)进程的执行. 本信号不能被阻塞, 处理或忽略.

20) SIGTSTP (暂停/停止) 交互式停止信号, Ctrl-Z 发出这个信号

21) SIGTTIN 当后台作业要从用户终端读数据时, 终端驱动程序产生SIGTTIN信号

22) SIGTTOU 当后台作业要往用户终端写数据时, 终端驱动程序产生SIGTTOU信号

23) SIGURG 有”紧急”数据或网络上带外数据到达socket时产生.

24) SIGXCPU 超过CPU时间资源限制. 这个限制可以由getrlimit/setrlimit来读取/改变。

25) SIGXFSZ 当进程企图扩大文件以至于超过文件大小资源限制。

26) SIGVTALRM 虚拟时钟信号. 类似于SIGALRM, 但是计算的是该进程占用的CPU时间.

27) SIGPROF (梗概时间超时) setitimer(2)函数设置的梗概统计间隔计时器(profiling interval

timer)

28) SIGWINCH 窗口大小改变时发出.

29) SIGIO(异步I/O) 文件描述符准备就绪, 可以开始进行输入/输出操作.

30) SIGPWR 电源失效/重启动

31) SIGSYS 非法的系统调用。

在以上列出的信号中,

程序不可捕获、阻塞或忽略的信号有:SIGKILL,SIGSTOP

不能恢复至默认动作的信号有:SIGILL,SIGTRAP

默认会导致进程流产的信号有:SIGABRT,SIGBUS,SIGFPE,SIGILL,SIGIOT,SIGQUIT,SIGSEGV,SIGTRAP,SIGXCPU,SIGXFSZ

默认会导致进程退出的信号有:SIGALRM,SIGHUP,SIGINT,SIGKILL,SIGPIPE,SIGPOLL,SIGPROF,SIGSYS,SIGTERM,SIGUSR1,SIGUSR2,SIGVTALRM

默认会导致进程停止的信号有:SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU

默认进程忽略的信号有:SIGCHLD,SIGPWR,SIGURG,SIGWINCH

此外,SIGIO在SVR4是退出,在4.3BSD中是忽略;SIGCONT在进程挂起时是继续,否则是忽略,不能被阻塞。

在Unix/Linux中signal函数是比较复杂的一个,其定义原型如下:

void (*signal(int signo,void (*func)(int))) (int)

这个函数中,最外层的函数体

void (* XXX

)(int)表明是一个指针,指向一个函数XXX的指针,XXX所代表的函数需要一个int型的参数,返回void

signal(int signo, void(*func)(int))是signal函数的主体.

需要两个参数int型的signo以及一个指向函数的函数.

void (*func)(int).

正是由于其复杂性,在[Plauger 1992]用typedef来对其进行简化

typedef void Sigfuc(int);//这里可以看成一个返回值 .

再对signal函数进行简化就是这样的了

Sigfunc *signal(int,Sigfuc *);

在signal.h头文件中还有以下几个定义

#define SIG_ERR (void (*)())-1

#define SIG_DFL (void (*)())0

#define SIG_IGN (void (*)())1

处理不当导致的问题请参照下面网址

http://www.diybl.com/course/3_program/c++/cppjs/20090831/173152.html

分享:

a4c26d1e5885305701be709a3d33442f.png喜欢

0

a4c26d1e5885305701be709a3d33442f.png赠金笔

加载中,请稍候……

评论加载中,请稍候…

发评论

登录名: 密码: 找回密码 注册记住登录状态

昵   称:

评论并转载此博文

a4c26d1e5885305701be709a3d33442f.png

发评论

以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/141232.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 简述51单片机的内部结构_51单片机的硬件结构及其作用

    简述51单片机的内部结构_51单片机的硬件结构及其作用【1.基本组成】单片机是在一块芯片中集成了CPU、RAM、ROM、定时/计数器和多功能I/O等计算机所需要的基本功能部件的大规模集成电路,又称MCU。51单片机内包含下列几个部件:一个8位CPU一个片内震荡器及时钟电路一个片内4KBROM程序存储器128字节RAM数据存储器可寻址64KB外部数据存储器和64KB外部程序存储空间的控制电路32条可编程的I/O线(4个8位并行I/O端口)两个16位的定时/计数器一个可编程全双工串行口5个中断源、两个优先级嵌套中断结构

    2022年10月4日
    3
  • Redis 修改默认端口号 修改配置文件 redis.windows.conf[通俗易懂]

    Redis 修改默认端口号 修改配置文件 redis.windows.conf[通俗易懂]简单说明一下Redis修改端口号的方法,本文用的是修改redis.windows.conf文件的方式,主要代码已经用橙色标记以便于各位伙伴直接复制使用。1.首先找到redis.windows.conf文件的位置,然后右键选择工具打开,如下图:2.打开之后可以直接Ctrl+F快捷键搜索port63或者port6379前提是你之前没有修改过端口号,或者直接下…

    2022年9月17日
    4
  • html圣杯布局,三种实现圣杯布局方法「建议收藏」

    html圣杯布局,三种实现圣杯布局方法「建议收藏」本文介绍三种实现圣杯布局的方法,前两种可归为一类,与第三种方法差别在于加载顺序不同。圣杯布局实现1:步骤1:给出HTML结构:圣杯布局1*{margin:0;padding:0;text-Align:center;}#top{background:#666;height:60px;}#left{background:#E79F6D;}#content{background:…

    2022年6月24日
    47
  • tasklist命令

    tasklist命令[align=center][size=large]Tasklist命令[/size][/align]Tasklist命令用来显示运行在本地或远程计算机上的所有进程,带有多个执行参数使用格式  Tasklist[/Ssystem[/Uusername[/P[password]]]][/M[module]|/SVC|/V][/FIfilter][/F…

    2022年5月3日
    50
  • 电脑很大,电脑内存很大为什么还是很卡「建议收藏」

    电脑很大,电脑内存很大为什么还是很卡「建议收藏」2019-10-09阅读(121)”电脑反应慢原因:1.电脑反应太慢,第一我们打开任务管理器,检查CPU资源的使用,若某个程序的CPU资源占用一直比较高(比如占到50%以上),系统速度就会明显变慢。因一般情况下,除大型游戏程序之外,应用程序在运行过程中只是瞬间占用较高,而不会一直持续2019-10-09阅读(132)一.清理垃圾在Windows在安装和使用过程中都会产生相当多的垃圾文件,包括临时文…

    2022年5月5日
    332
  • Web应用的UML建模与.NET框架开发

    Web应用的UML建模与.NET框架开发

    2022年3月12日
    341

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号