目次
信号
什么是信号
信号的产生
信号的生存与处置惩罚
信号的捕获
信号的捕获流程
signal函数
sigaction函数
sigprocmask函数
信号
什么是信号
信号是Linux提供的一种向指定历程发送特定变乱的方式。
Linux中规定了64种信号,此中1到31号为不可靠信号(大概丢失),32到64号为可靠信号(不大概丢失)。
注:绝大多数的默认操纵都是停止历程。
信号取值名称作用默认操纵1SIGHUP挂起2SIGINT停止3SIGQUIT退出4SIGILL非法指令5SIGTRAP断点或陷阱指令6SIGABRTabort发出的信号7SIGBUS非法内存访问8SIGFPE浮点非常9SIGKILLkill信号不能被忽略、处置惩罚和壅闭10SIGUSR1用户信号111SIGSEGV无效内存访问12SIGUSR2用户信号213SIGPIPE管道粉碎,没有读端的管道写数据14SIGALRMalarm发出的信号15SIGTERM停止信号16SIGSTKFLT栈溢出17SIGCHLD子历程退出默认忽略18SIGCONT历程继续19SIGSTOP历程制止不能被忽略、处置惩罚和壅闭20SIGTSTP历程制止21SIGTTIN历程制止,配景历程从终端读数据时22SIGTTOU历程制止,配景历程向终端写数据时23SIGURGIO有告急数据到达当进步程默认忽略24SIGXCPU历程的CPU时间片到期25SIGXFSZ文件巨细的超出上限26SIGVTALRM捏造时钟超时27SIGPROFprofile时钟超时28SIGWINCH窗口巨细改变默认忽略29SIGIOIO干系30SIGPWR关机默认忽略31SIGSYS体系调用非常 信号通常履历以下三个阶段,产生、生存、递达(处置惩罚)。处于生存时期的信号处于一个叫未决的状态。可以简朴明白为信号到了,但未处置惩罚的状态。
举个例子,你的朋侪让你给他买瓶汽水,但由于你手头上有更加告急的事,以是你岑寂地记下给他买瓶汽水这个信号比及你忙完后才去实验。此时你对信号的处置惩罚是壅闭,信号在被递达前都处于未决状态。固然,除了壅闭你也可以选择忽略,忽略则是信号到了但是你直接无视。
信号的产生
信号的产生是异步的,他可以大概使一个正在实验的历程被异步打断,转而行止理一个突发变乱。
信号的产生大抵有以下五种缘故原由,但从始至终信号都是有OS来发送的。
- 通过kill下令向指定历程发信号。例:kill -2 8888 (2是信号取值,代表2号信号。8888是一个历程的pid)
- 键盘也可以产生信号(Ctrl+c 就相当于向当前举行发送2号信号)
- 体系调用,比方 int kill(pid_t pid,int sig)函数。
- 软件条件,比方管道读端关闭,写端不绝写,那么OS就会向他发送13号信号SIGPIPE关闭写端。(这就是读端关闭写端就不写了的缘故原由)
- 非常,出现非常历程制止运行也是OS对其发送了信号。
信号的生存与处置惩罚
每个历程都有一个对应的task_struct,而在task_struct中有一个管理信号的结构。这个结构告急分为三部门。pending、block是两张位图,pengding的每个位置都代表对应的信号,0或1代表该信号是否未决(到达但未处置惩罚)。clock的每个位置同样代表对应的信号,0或1代表该信号是否被壅闭。而handle是一个函数指针数组,他的每个位置都对应信号的处置惩罚方法,不修改则为默认,可以通过体系调用举行自界说。
当信号到来时,OS就会遍历pending位图,为0则检察下一个比特位,为1则检察block位图的对应位置,此时block的该比特位为1则不做处置惩罚(被壅闭),为0则将对应位置pending置0再实验对应位置的handle操纵。
信号的捕获
信号的捕获流程
内核态对比用户态最显着的区别的内核态拥有更大的权利。以是举行自界说的信号处置惩罚时,要从内核态回到用户态,这是对操纵体系的掩护,防止用户界说的函数在内核态举行非法操纵。
signal函数
作用:捕获一个指定信号,设定该信号的操纵方法。
- #include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
- 第一个参数signum代表信号的取值。
- 第二个参数有三种,第一种是返回值为void,参数为int的自界说函数指针;第二种是 SIG_IGN 代表忽略一个信号;SIG_DFL代表默认处置惩罚。
- #include <iostream>
- #include <unistd.h>
- #include <signal.h>
- void sigcb(int sig)
- {
- std::cout << "get a sig : " << sig << std::endl;
- }
- int main()
- {
- signal(2, sigcb);
- while (true)
- {
- std::cout << "process is running , pid : " << getpid() << std::endl;
- sleep(1);
- }
- return 0;
- }
复制代码 向历程3348发送2号信号,历程收到信号后实验了sigcb函数。
sigaction函数
作用:捕获一个指定信号,设定该信号的操纵方法。
- #include <signal.h> int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
- 第一个参数signum代表信号的取值。
- 第二个参数设定新的结构体(结构体中包罗handle函数指针,与signal中的划一)
- 第三个参数输出原来的结构体
- #include <iostream>
- #include <unistd.h>
- #include <signal.h>
- void sigcb(int sig)
- {
- std::cout << "get a sig : " << sig << std::endl;
- }
- /*struct sigaction {
- void (*sa_handler)(int);
- void (*sa_sigaction)(int, siginfo_t *, void *);
- sigset_t sa_mask;
- int sa_flags;
- void (*sa_restorer)(void);
- }
- */
- int main()
- {
- struct sigaction act;
- act.sa_handler = sigcb;
- sigaction(2, &act, nullptr);
- while (true)
- {
- std::cout << "process is running , pid : " << getpid() << std::endl;
- sleep(1);
- }
- return 0;
- }
复制代码 sigprocmask函数
作用: sigprocmask函数用于查抄或修改当进步程的信号屏蔽字(signal mask)
- #include <signal.h> int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
- 第一个参数,操纵标志,决定怎样修改信号屏蔽字。有三个选项: SIG_BLOCK:把 set 指向的信号会合的信号添加到当前信号屏蔽字中。 SIG_UNBLOCK:从当前信号屏蔽字中移除 set 指向的信号会合的信号。 SIG_SETMASK:用 set 指向的信号集更换当前信号屏蔽字。
- const sigset_t *set:指向要修改的新信号集的指针。
- sigset_t *oldset:如果不为 NULL,则存储之前的信号屏蔽字。
- #include <iostream>
- #include <unistd.h>
- #include <signal.h>
- void PrintfPending(sigset_t &pending)
- {
- std::cout << "cur process pid : " << getpid() << "\n";
- std::cout << "pending signo :";
- for (int signo = 31; signo >= 1; signo--)
- {
- if (sigismember(&pending, signo))
- {
- std::cout << 1;
- }
- else
- {
- std::cout << 0;
- }
- }
- std::cout << "\n";
- }
- int main()
- {
- signal(2, handler);
- sigset_t block_set, old_set;
- sigemptyset(&block_set);
- sigemptyset(&old_set);
- sigaddset(&block_set, 2);
- sigprocmask(SIG_BLOCK, &block_set, &old_set);
- while (true)
- {
- sigset_t pending;
- sigpending(&pending);
- PrintfPending(pending);
- sleep(2);
- }
- return 0;
- }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金 |