linux下sigaction函数,Linux sigaction函数 sa_flags的值

开始对sa_flags有疑问,网上搜到都是这一个程序,就复制来说事:

代码:

1 #include

2 #include

3 #include

4 #include

5

6 void show_handler (int sig)

7 {

8         printf ("i got signal %d\n",sig);

9         int i;

10         for (i = 0 ; i < 5; i++)

11         {

12                 printf ("i= %d\n",i);

13                 sleep(1);

14         }

15 }

16

17 int main(void)

18 {

19         int i = 0;

20         struct sigaction act , oldact;

21         act.sa_handler = show_handler;

22         sigaddset (&act.sa_mask, SIGQUIT);  /*这个信号用

户终端键入ctrl+\时产生,送至前台所有进程,不仅终止前台进

程组,还产生core文件,这一程序的作用是把SIGQUIT加入信号>    集,对CTRL+\的屏蔽*/

23         act.sa_flags =SA_RESETHAND|SA_NODEFER ; /*if sig    nal got ,set to SIG_DEF*/

24         //act.sa_flags = 0; //(3)

25         //sigprocmask(SIG_BLOCK, &act.sa_mask,NULL);

26         //this can be used for add sigset mask

27         sigaction(SIGINT,&act,&oldact);

28         while (1)

29         {

30                 sleep (1);

31                 printf ("sleeping %d\n", i);

32                 i++;

33         }

34 }

sigaction.sa_flags     控制内核对该信号的处理标记

SA_NODEFER         一般情况下, 当信号处理函数运行时,内核将阻塞。但是如果设置了SA_NODEFER标记, 那么在该信号处理函数运行时,内核将不会阻塞该信号。 SA_NODEFER是这个标记的正式的POSIX名字(还有一个名字SA_NOMASK,为了软件的可移植性,一般不用这个名字)

SA_RESETHAND      当调用信号处理函数时,将信号的处理函数重置为缺省值。 SA_RESETHAND是这个标记的正式的POSIX名字(还有一个名字SA_ONESHOT,为了软件的可移植性,一般

上面是对sa_flags中常用的两个值的解释.]

疑问1:

act.sa_flags =SA_RESETHAND|SA_NODEFER ;

这一行程序中"|"按位或运算

那么sa_flags到底是什么样的值可以这样赋值,查看这个结构定义的根源:

/usr/include/bits/sigaction.h

/* Bits in `sa_flags'.  */

54 #define SA_NOCLDSTOP  1          /* Don't send SIGCHLD when children stop.  */

55 #define SA_NOCLDWAIT  2          /* Don't create zombie on child death.  */

56 #define SA_SIGINFO    4          /* Invoke signal-catching function with

57                                     three arguments instead of one.  */

58 #if defined __USE_UNIX98 || defined __USE_MISC

59 # define SA_ONSTACK   0x08000000 /* Use signal stack by using `sa_restorer'. */

60 #endif

61 #if defined __USE_UNIX98 || defined __USE_MISC || defined __USE_XOPEN2K8

62 # define SA_RESTART   0x10000000 /* Restart syscall on signal return.  */

63 # define SA_NODEFER   0x40000000 /* Don't automatically block the signal when

64                                     its handler is being executed.  */

65 # define SA_RESETHAND 0x80000000 /* Reset to SIG_DFL on entry to handler.  */

66 #endif

67 #ifdef __USE_MISC

68 # define SA_INTERRUPT 0x20000000 /* Historical no-op.  */

可以看到sa_flags的值可以是上面的值在值的定义中看到每个宏都有一个数字相对应:这样这句程序就不难理解啦,也就是说它同时定义啦 SA_NODEFER和 SA_RESETHAND,都对信号处理函数作用。

看运行结果:

www.linuxidc.com@Ubuntu:~/apuestudy/10/3$ ./sig3

sleeping 0

sleeping 1

^Ci got signal 2

i= 0

i= 1

^C

这里先ctrl+c进入信号处理函数,然后ctrl+c终止程序,应为有sa_resethan是在信号处理函数中ctrl+c变为默认,这样就终止

sleeping 0

sleeping 1

^\退出

这个简单,就没进信号处理函数,

sleeping 0

^Ci got signal 2

i= 0

i= 1

^\i= 2

^\i= 3

i= 4

退出

这个进入信号处理函数,键入ctrl+\,由于 sigaddset (&act.sa_mask, SIGQUIT)键所以对ctrl+\屏蔽,但回到主进程中依然会处理该信号,故退出,

好啦:现在把sa_flags改为sa_nodefer

i got signal 2

i= 0

i= 1

i= 2

i= 3

^Ci got signal 2

i= 0

i= 1

^Ci got signal 2

i= 0

i= 1

^\i= 2

i= 3

i= 4

i= 2

i= 3

i= 4

i= 4

退出

呵呵,sigaddset (&act.sa_mask, SIGQUIT);信号处理函数函数依然屏蔽,到主函数停止,

但是可以在信号处理函数中多次ctrl+c而不会推出,因为没有 SA_RESETHAND   所以不会恢复默认处理,还有个有趣的现象是i的输出顺序,这个没有信号队列的处理机制,小弟水平有限。

再看看只有 SA_RESETHAND

sleeping 0

^Ci got signal 2

i= 0

i= 1

^Ci= 2

i= 3

^\i= 4

这里有可能有人问, SA_RESETHAND 恢复默认,为什么没有停止,应为没有设置sa_nodefer

所以处理函数是对ctrl+c是阻塞的,只有到主函数中才有作用,

还有一个结果

sleeping 0

^Ci got signal 2

i= 0

i= 1

^\i= 2

^Ci= 3

i= 4

这个和上面的一样,但是在信号处理函数中,我把ctrl+c与ctrl+\的执行顺序便啦,如果ctrl+\作用,则在最后有“退出”两个子,可是这两个顺序都没有,可见不管是那个执行,都是ctrl+c作用结束啦程序,这个可能与信号与信号优先级有关??水平有限,待高手

小弟刚自学linux编程,以上只是根据试验结果自己理解,如有错误,恳请指教,

Q:915311043

今天又看程序发现以前有不完全的理解:

如果我们只用SA—NODEFER,这样会发现只要ctrl+c键入一次,就会运行一次handler(信号处理函数);

而你对信号作用的设置,只是对信号处理函数有作用,在主函数中ctrl+\仍然会终止程序,但是为什么键入ctrl+c不会终止,应为sigaction函数捕捉的是sigint(ctrl+c产生的信号),所以会再次产生handler0b1331709591d260c1c78e86d0c51c18.png

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`sa_sigaction` 是一个结构体类型,在 C 语言中用于指定信号处理函数的方式。它通常用于设置信号处理函数,以便在程序收到特定信号时执行相应的操作。 它的完整定义如下: ```c struct sigaction { void (*sa_handler)(int); void (*sa_sigaction)(int, siginfo_t *, void *); sigset_t sa_mask; int sa_flags; void (*sa_restorer)(void); }; ``` 其中,`sa_handler` 和 `sa_sigaction` 两个字段是用于指定信号处理函数的指针。`sa_handler` 字段指定了一个简单的信号处理函数,而 `sa_sigaction` 字段指定了一个更复杂的信号处理函数,可以接收额外的信息。 `sa_mask` 字段表示在处理信号时需要阻塞的其他信号集合。当处理某个信号时,通常需要阻塞其他信号,以避免信号处理函数被其他信号中断。 `sa_flags` 字段表示信号处理的行为标志,可以控制信号处理函数的行为。 `sa_restorer` 字段是一个已过时的字段,通常不再使用。 使用 `sigaction` 函数可以将 `struct sigaction` 结构体中的信号处理函数注册到特定的信号上,示例代码如下: ```c #include <stdio.h> #include <signal.h> void handle_signal(int signum) { printf("Received signal: %d\n", signum); } int main() { struct sigaction sa; sa.sa_handler = handle_signal; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGINT, &sa, NULL); // 注册 SIGINT 信号处理函数 // 一些其他的程序逻辑... return 0; } ``` 在上述示例中,`handle_signal` 函数被注册为 `SIGINT` 信号的处理函数,当程序收到 `SIGINT` 信号时,会执行 `handle_signal` 函数

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值