【Linux】多历程基础--信号

打印 上一主题 下一主题

主题 691|帖子 691|积分 2073

信号



  • 信号是向历程通报消息的一种机制,发生事件时通过信号向历程进行通知,从而改变历程的举动,信号在软件层次上模仿中断,也叫软件中断,处理优先级较高
  • 对于前台历程可以通过特殊的字符发送信号,比方Ctrl+C即给当进步程发送一个SIGINT中断信号。
  • kill下令也是向历程发送信号,可以通过kill -l查询信号,比方kill -9 pid即向pid历程发送停止信号
  • 信号通信较为简单、不能携带大量的信息、优先级较高
  • 信号集有阻塞信号集和未决信号集,通过位视图标识,阻塞信号是指阻止信号被处理,未决是一种状态指的是从信号产生到信号处理的这段时间,先查询未决再查询阻塞。
  • 信号的默认处理动作为:Term停止历程、lgn忽略信号、Core停止历程并天生Core文件默认大小为0,可以通过ulimit -a查看,并通过ulimit -c unlimited进行大小修改即可看到相应文件,一样平常和gdb配合使用在gdb中可以通过core-file core查看文件、Stop暂定历程、Cont继续执行被停息的历程,man 7 signal可查询具体信息
常见信号

信号代号信号名称说 明默认动作1SIGHUP该信号让历程立刻关闭,然后重新读取配置文件之后重启停止历程2SIGINT步伐中断信号,用于中断前台历程。相称于输出 Ctrl+C 快捷键停止历程3SIGQUIT和SIGINT类似, 但由QUIT字符(通常是Ctrl+/)来控制。 历程在因收到SIGQUIT退出时会产生core文件, 在这个意义上类似于一个步伐错误信号。停止历程8SIGFPE在发生致命的算术运算错误时发出。不仅包括浮点运算错误,还包括溢出及除数为 0 等其他全部的算术运算错误停止历程、产生core文件9SIGKILL用来立刻竣事步伐的运行。本信号不能被阻塞、处理和忽略。般用于逼迫中断历程停止历程–逼迫11SIGSEGV试图访问未分配给本身的内存, 或试图往没有写权限的内存地址写数据,段错误停止历程产生core文件13SIGPIPE管道破碎。这个信号通常在历程间通信产生,比如采用FIFO(管道)通信的两个历程,读管道没打开或者不测停止就往管道写,写历程会收到SIGPIPE信号。停止历程14SIGALRM时钟定时信号,计算的是实际的时间或时钟时间。alarm 函数使用该信号停止历程15SIGTERM正常竣事历程的信号,kill 下令的默认信号。假如历程已经发生了题目,那么这个信号是无法正常中断历程的,这时我们才会实验 SIGKILL 信号,也就是信号 9停止历程17SIGCHLD子历程竣事时, 父历程会收到这个信号。忽略信号18SIGCONT该信号可以让停息的历程规复执行。本信号不能被阻断继续/忽略19SIGSTOP该信号可以停息前台历程,相称于输入 Ctrl+Z 快捷键。本信号不能被阻断停止历程 信号定时函数

  1. #include <unistd.h>
  2. 1. unsigned int alarm(unsigned int seconds);
  3. //alarm不阻塞,程序正常执行,在指定的时间后向进程发送一个信号,通常是SIGALRM信号。
  4. //参数seconds:指定多少秒后发送SIGALRM信号给调用进程。如果seconds为0,则取消任何现有的闹钟(如果有的话)。
  5. //返回值:如果之前已有闹钟设置,该函数返回剩余的秒数并从新设置的秒数计时,如果没有设置过闹钟,返回0。
  6. //SIGALRM:默认终止当前进程
  7. #include <sys/time.h>
  8. 2. int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);
  9. //成功时返回0,出错时返回-1,并设置errno
  10. //周期性定时可代替alarm
  11. //which:指定要设置的计时器类型,一般为ITIMER_REAL真实时间返回SIGALRM
  12. //value:指向一个itimerval结构的指针
  13. struct itimerval {
  14.    struct timeval it_interval; /* 下一次间隔 */
  15.     struct timeval it_value;   /* 多长时间开始计时 */
  16. };
  17. struct timeval{
  18.     time_t tv_sec;//秒数
  19.     suseconds_t tv_usec;//微秒
  20. }
  21. ovalue(可选):指向一个itimerval结构的指针,用来存储之前设置的定时器值。如果不需要旧值,可以传入NULL。
  22. struct itimerval new_value;
  23. //设置间隔
  24. new_value.it_interval.tv_sec=2;
  25. new_value.it_interval.tv_usec=0;
  26. //设置延迟
  27. new_value.it_value.tv_sec=3;
  28. new_value.it_value.tv_usec=0;
  29. //使用
  30. if (setitimer(ITIMER_REAL, &new_value, NULL) == -1) {
  31.         perror("setitimer error");
  32.         return 1;
  33.     }
复制代码
信号捕捉函数

  1. #include <signal.h>
  2. 1. typedef void (*sighandler_t)(int);//函数指针,输入int返回void
  3. sighandler_t signal(int signum, sighandler_t handler);
  4. //成功情况下,返回以前的信号处理函数指针。
  5. //signum:要处理的信号编号,如SIGINT(2,对应Ctrl+C中断)、SIGTERM(15,程序终止信号)等。
  6. //handler:处理函数指针。可以是以下几种情况之一:
  7. /*
  8. SIG_DFL:恢复信号的默认处理行为。
  9. SIG_IGN:忽略该信号。
  10. 自定义函数指针:当进程接收到signum信号时,将调用此函数.
  11. */
  12. //具体使用
  13. void myalarm(int num){
  14.     std::cout<<"捕捉的信号编号为"<<num<<std::endl;
  15. }
  16. signal(SIGALRM,myalarm);
  17. alarm(3);
  18. 2. int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
  19. //成功时返回0,失败时返回-1,并设置errno
  20. //signum:要处理的信号编号。
  21. //act:指向struct sigaction结构的指针,用于设置新的信号处理行为。该结构定义如下:
  22. struct sigaction {
  23.     void (*sa_handler)(int);  // 信号处理函数指针,捕捉后的处理函数
  24.     void (*sa_sigaction)(int, siginfo_t *, void *); // 更高级的信号处理函数指针,支持传递附加信息
  25.     sigset_t sa_mask;// 处理信号时临时阻塞的信号集
  26.     int sa_flags;// 控制信号处理的标志,如SA_RESTART, SA_NODEFER等
  27.     void (*sa_restorer)(void); // 仅供系统内部使用,通常设为NULL
  28. };
  29. //oldact通常设为NULL
  30. //具体使用
  31. void myalarm(int num){
  32.     std::cout<<"捕捉的信号编号为"<<num<<std::endl;
  33. }
  34. struct sigaction act;
  35. act.sa_flags=0;
  36. act.sa_handler=myalarm;
  37. sigemptyset(&act.sa_mask);//清空阻塞集
  38. sigaction(SIGALRM,&act,NULL);
  39. alarm(3);
复制代码
信号集



  • 信号集有阻塞信号集和未决信号集,通过位视图标识,阻塞信号是指阻止信号被处理,未决是一种状态指的是从信号产生到信号处理的这段时间,先查询未决再查询阻塞。
  1. #include <signal.h>
  2. int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
  3. //设置内核信号,包括阻塞、接触阻塞、替换
  4. //成功时返回0,失败时返回-1,并设置errno。
  5. //how:决定如何对内核阻塞信号集处理,可以是以下值之一:
  6. /*
  7. SIG_BLOCK:将set指定的信号集所包含的信号添加到当前的阻塞信号集中。
  8. SIG_UNBLOCK:从当前的阻塞信号集中移除set指定的信号。
  9. SIG_SETMASK:将当前的阻塞信号集设置为set指定的信号集,完全替换原有集合。
  10. */
  11. //set:指向一个sigset_t类型的指针,表示要修改的信号集合。具体操作根据how参数决定。
  12. //oldset一般为NULL
  13. int sigpending(sigset_t *set);
  14. //查询当前进程中哪些信号是未决的,不会清除未决信号的状态。
  15. //成功时返回0。出错时返回-1,并设置errno。
  16. //set:指向sigset_t类型的指针,用来存放查询结果。函数执行成功后,set中将包含当前进程所有未决信号的集合。
  17. //具体使用
  18. sigset_t set;//创建自定义信号集
  19. sigemptyset(&set);//初始化
  20. sigaddset(&set,SIGQUIT)
  21. sigaddset(&set,SIGINT)//信号集中加入SIGQUIT、SIGINT信号,位视图法,将相应信号位置1
  22. sigprocmask(SIG_BLOCK,&set,NULL)//将内核中相应的信号阻塞,位视图法,将相应信号位置1
  23. sigpending(&set)//查询哪些信号是未决的
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

北冰洋以北

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表