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

article/2025/10/16 6:32:15

开始对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


http://chatgpt.dhexx.cn/article/d6xI3yYs.shtml

相关文章

Linux signal、sigaction的使用总结

目录 一、什么是信号 二、信号的种类 三、信号的处理 —— signal()函数 四、信号处理 —— sigaction()函数&#xff08;扑获信号&#xff09; 五、扑获信号示例 一、什么是信号 信号是UNIX和Linux系统响应某些条件而产生的一个事件&#xff0c;接收到该信号的进程会相应地采取…

sigaction 函数

今天查一个问题&#xff0c;SIGWINCH的处理函数一直不执行&#xff0c;耽搁了不少时间&#xff0c;最后发现是另外一个地方也设置了&#xff0c;处理函数是另外的。。。。 顺便记录下使用例子&#xff1a; 使用 sigaction 函数&#xff1a; signal 函数的使用方法简单&#xf…

信号、signal 函数、sigaction 函数

文章目录 1.信号的基本概念2.利用 kill 命令发送信号3.信号处理的相关动作4.信号与 signal 函数4.1 signal 函数示例一4.2 signal 函数示例二 5.利用 sigaction 函数进行信号处理6.利用信号处理技术消灭僵尸进程 1.信号的基本概念 发送信号是进程之间常用的通信手段。信号用来…

linux sigaction详解

参看文档&#xff1a; https://blog.csdn.net/weixin_43743847/article/details/90299204https://blog.csdn.net/u010150046/article/details/77344438https://bbs.csdn.net/topics/370255407 一&#xff1a;函数原型介绍 int sigaction(int signum, const struct sigaction …

sigaction函数

#include <signal.h> int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact); //The sigaction() system call is used to change the action taken by a process on receipt of a specific signal. sigaction()系统调用用于改变进程在接收…

c语言sigaction,c语言信号处理sigaction

c语言信号处理sigaction (2011-04-18 23:45:19) 标签: c语言 信号处理 sigaction sighup it 分类: c 信号安装函数sigaction(int signum,const struct sigaction *act,struct sigaction *oldact)的第二个参数是一个指向sigaction结构的指针(结构体名称与函数名一样,千万别弄…

linux中sigaction函数详解

一、函数原型&#xff1a;sigaction函数的功能是检查或修改与指定信号相关联的处理动作&#xff08;可同时两种操作&#xff09; int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);signum参数指出要捕获的信号类型&#xff0c;act参数指定新…

Qt线程QThread详解

目录 前言1.QThread介绍2.QThread示例一3.QThread示例二4.线程同步 前言 在程序中使用线程可以提高程序的性能、并发性、响应性和稳定性&#xff0c;使得程序设计更加灵活和简单。但是&#xff0c;线程编程也有一些挑战&#xff0c;如线程安全性和死锁等问题需要格外注意。我们…

PyQT5 多线程 QThread

PyQT5 多线程 在常规的界面软件中&#xff0c;需要将UI线程和工作线程加以区分&#xff0c;主要原因是某些工作线程很复杂且耗时&#xff0c;比如下载某个文件或者长时间的计算&#xff0c;当执行这些进程时&#xff0c;UI主进程会被阻塞&#xff0c;界面会出现未响应的状态&a…

QThread之moveToThread用法

一、怎么用 使用一个QObject作为Worker&#xff0c;并moveToThread到线程上&#xff0c;那么这个QObject生存在此线程上&#xff0c;其信号会在此线程上发射&#xff0c;其槽函数在此线程上执行。 意味着什么&#xff0c;意味着多线程操作时&#xff0c;若通过信号槽方式&…

Qt 多线程编程的 QThread 类 (详细)

本文结构如下&#xff1a; 概述优雅的开始我们的多线程编程之旅 我们该把耗时代码放在哪里&#xff1f;再谈 moveToThread()启动线程前的准备工作 开多少个线程比较合适&#xff1f;设置栈大小启动线程/退出线程 启动线程优雅的退出线程操作运行中的线程 获取状态 运行状态线程…

QT之多线程(QThread)的简单使用

一、线程简述 线程&#xff08;thread&#xff09;是操作系统能够进行运算调度的最小单位。一条线程指的是进程中一个单一顺序的控制流&#xff0c;它被包含在进程之中&#xff0c;是进程中的实际运作单位。一个进程中可以并发多个线程&#xff0c;每条线程并行执行不同的任务…

Qt 之 QThread(深入理解)

作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 为了让程序尽快响应用户操作,在开发应用程序时经常会使用到线程。对于耗时操作如果不使用线程,UI界面将会长时间处于停滞状态,这种情况是用户非常不愿意看到的,我们可以用线程来解决这个问题。 前面,已…

Qt线程:QThread

一、描述 一个QThread对象管理程序内的一个线程&#xff0c;QThreads在run()中开始执行。默认情况下&#xff0c;run()通过调用exec()启动事件循环&#xff0c;并在线程内部运行一个Qt事件循环。 可以通过使用 QObject::moveToThread() 将对象移动到线程来使用它们。 class W…

PyQt中的多线程QThread示例

PyQt中的多线程 一、PyQt中的多线程二、创建线程2.1 设计ui界面2.2 设计工作线程2.3 主程序设计 三、运行结果示例 一、PyQt中的多线程 传统的图形用户界面应用程序都只有一个执行线程&#xff0c;并且一次只执行一个操作。如果用户从用户界面中调用一个比较耗时的操作&#x…

【Qt】Qt的线程(两种QThread类的详细使用方式)

Qt提供QThread类以进行多任务处理。与多任务处理一样&#xff0c;Qt提供的线程可以做到单个线程做不到的事情。例如&#xff0c;网络应用程序中&#xff0c;可以使用线程处理多种连接器。 QThread继承自QObject类&#xff0c;且提供QMutex类以实现同步。线程和进程共享全局变量…

Qt - 一文理解QThread多线程(万字剖析整理)

目录 为什么需要多线程QThread使用方法new QThread Class & Override run()new Object Class & moveToThread(new QThread) connect事件循环源码分析如何正确退出线程堆栈大小优先级线程间通讯线程同步互斥锁读写锁信号量条件变量 可重入与线程安全QObject的可重入性开…

Qt 线程中QThread的使用

文章目录 Qt 线程中QThread的使用1. 线程类 QThread1.1 常用共用成员函数1.2 信号槽1.3 静态函数1.4 任务处理函数 2. 使用方式 12.2 示例代码3. 使用方式 23.1 操作步骤3.2 示例代码 Qt 线程中QThread的使用 在进行桌面应用程序开发的时候&#xff0c; 假设应用程序在某些情况…

Qt之QThread(深入理解)

简述 为了让程序尽快响应用户操作&#xff0c;在开发应用程序时经常会使用到线程。对于耗时操作如果不使用线程&#xff0c;UI界面将会长时间处于停滞状态&#xff0c;这种情况是用户非常不愿意看到的&#xff0c;我们可以用线程来解决这个问题。 前面&#xff0c;已经介绍了…

Qt之QThread介绍(常用接口及实现、自动释放内存、关闭窗口时停止线程运行、同步互斥)

在程序设计中&#xff0c;为了不影响主程序的执行&#xff0c;常常把耗时操作放到一个单独的线程中执行。Qt对多线程操作有着完整的支持&#xff0c;Qt中通过继承QThread并重写run()方法的方式实现多线程代码的编写。针对线程之间的同步与互斥问题&#xff0c;Qt还提供了QMutex…