信号
- 信号是向历程通报消息的一种机制,发生事件时通过信号向历程进行通知,从而改变历程的举动,信号在软件层次上模仿中断,也叫软件中断,处理优先级较高
- 对于前台历程可以通过特殊的字符发送信号,比方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 快捷键。本信号不能被阻断停止历程 信号定时函数
- #include <unistd.h>
- 1. unsigned int alarm(unsigned int seconds);
- //alarm不阻塞,程序正常执行,在指定的时间后向进程发送一个信号,通常是SIGALRM信号。
- //参数seconds:指定多少秒后发送SIGALRM信号给调用进程。如果seconds为0,则取消任何现有的闹钟(如果有的话)。
- //返回值:如果之前已有闹钟设置,该函数返回剩余的秒数并从新设置的秒数计时,如果没有设置过闹钟,返回0。
- //SIGALRM:默认终止当前进程
- #include <sys/time.h>
- 2. int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);
- //成功时返回0,出错时返回-1,并设置errno
- //周期性定时可代替alarm
- //which:指定要设置的计时器类型,一般为ITIMER_REAL真实时间返回SIGALRM
- //value:指向一个itimerval结构的指针
- struct itimerval {
- struct timeval it_interval; /* 下一次间隔 */
- struct timeval it_value; /* 多长时间开始计时 */
- };
- struct timeval{
- time_t tv_sec;//秒数
- suseconds_t tv_usec;//微秒
- }
- ovalue(可选):指向一个itimerval结构的指针,用来存储之前设置的定时器值。如果不需要旧值,可以传入NULL。
- struct itimerval new_value;
- //设置间隔
- new_value.it_interval.tv_sec=2;
- new_value.it_interval.tv_usec=0;
- //设置延迟
- new_value.it_value.tv_sec=3;
- new_value.it_value.tv_usec=0;
- //使用
- if (setitimer(ITIMER_REAL, &new_value, NULL) == -1) {
- perror("setitimer error");
- return 1;
- }
复制代码 信号捕捉函数
- #include <signal.h>
- 1. typedef void (*sighandler_t)(int);//函数指针,输入int返回void
- sighandler_t signal(int signum, sighandler_t handler);
- //成功情况下,返回以前的信号处理函数指针。
- //signum:要处理的信号编号,如SIGINT(2,对应Ctrl+C中断)、SIGTERM(15,程序终止信号)等。
- //handler:处理函数指针。可以是以下几种情况之一:
- /*
- SIG_DFL:恢复信号的默认处理行为。
- SIG_IGN:忽略该信号。
- 自定义函数指针:当进程接收到signum信号时,将调用此函数.
- */
- //具体使用
- void myalarm(int num){
- std::cout<<"捕捉的信号编号为"<<num<<std::endl;
- }
- signal(SIGALRM,myalarm);
- alarm(3);
- 2. int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
- //成功时返回0,失败时返回-1,并设置errno
- //signum:要处理的信号编号。
- //act:指向struct sigaction结构的指针,用于设置新的信号处理行为。该结构定义如下:
- struct sigaction {
- void (*sa_handler)(int); // 信号处理函数指针,捕捉后的处理函数
- void (*sa_sigaction)(int, siginfo_t *, void *); // 更高级的信号处理函数指针,支持传递附加信息
- sigset_t sa_mask;// 处理信号时临时阻塞的信号集
- int sa_flags;// 控制信号处理的标志,如SA_RESTART, SA_NODEFER等
- void (*sa_restorer)(void); // 仅供系统内部使用,通常设为NULL
- };
- //oldact通常设为NULL
- //具体使用
- void myalarm(int num){
- std::cout<<"捕捉的信号编号为"<<num<<std::endl;
- }
- struct sigaction act;
- act.sa_flags=0;
- act.sa_handler=myalarm;
- sigemptyset(&act.sa_mask);//清空阻塞集
- sigaction(SIGALRM,&act,NULL);
- alarm(3);
复制代码 信号集
- 信号集有阻塞信号集和未决信号集,通过位视图标识,阻塞信号是指阻止信号被处理,未决是一种状态指的是从信号产生到信号处理的这段时间,先查询未决再查询阻塞。
- #include <signal.h>
- int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
- //设置内核信号,包括阻塞、接触阻塞、替换
- //成功时返回0,失败时返回-1,并设置errno。
- //how:决定如何对内核阻塞信号集处理,可以是以下值之一:
- /*
- SIG_BLOCK:将set指定的信号集所包含的信号添加到当前的阻塞信号集中。
- SIG_UNBLOCK:从当前的阻塞信号集中移除set指定的信号。
- SIG_SETMASK:将当前的阻塞信号集设置为set指定的信号集,完全替换原有集合。
- */
- //set:指向一个sigset_t类型的指针,表示要修改的信号集合。具体操作根据how参数决定。
- //oldset一般为NULL
- int sigpending(sigset_t *set);
- //查询当前进程中哪些信号是未决的,不会清除未决信号的状态。
- //成功时返回0。出错时返回-1,并设置errno。
- //set:指向sigset_t类型的指针,用来存放查询结果。函数执行成功后,set中将包含当前进程所有未决信号的集合。
- //具体使用
- sigset_t set;//创建自定义信号集
- sigemptyset(&set);//初始化
- sigaddset(&set,SIGQUIT)
- sigaddset(&set,SIGINT)//信号集中加入SIGQUIT、SIGINT信号,位视图法,将相应信号位置1
- sigprocmask(SIG_BLOCK,&set,NULL)//将内核中相应的信号阻塞,位视图法,将相应信号位置1
- sigpending(&set)//查询哪些信号是未决的
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |