void signal_exit_func(int signo) { printf("exit signo is %d\n", signo); //CSingleton<CNet_TCPServer>::instance().stop_server(); } void signal_exit_handler() { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = signal_exit_func; sigaction(SIGINT, &sa, NULL);//当按下ctrl+c时,它的效果就是发送SIGINT信号 sigaction(SIGTERM, &sa, NULL);//kill pid sigaction(SIGQUIT, &sa, NULL);//ctrl+\代表退出SIGQUIT //SIGSTOP和SIGKILL信号是不可捕获的,所以下面两句话写了等于没有写 sigaction(SIGKILL, &sa, NULL);//kill -9 pid sigaction(SIGSTOP, &sa, NULL);//ctrl+z代表停止 //#define SIGTERM 15 //#define SIGKILL 9 //kill和kill -9,两个命令在linux中都有杀死进程的效果,然而两命令的执行过程却大有不同,在程序中如果用错了,可能会造成莫名其妙的现象。 //执行kill pid命令,系统会发送一个SIGTERM信号给对应的程序。 //执行kill -9 pid命令,系统给对应程序发送的信号是SIGKILL,即exit。exit信号不会被系统阻塞,所以kill -9能顺利杀掉进程。 }
本人编译报错:error: storage size of ‘sa’ isn’t known
struct sigaction sa;
解决方法是:新添加头文件bits/sigaction.h即可。
#include <signal.h>
#include <bits/sigaction.h>
-----
参考文章:https://blog.csdn.net/gatieme/article/details/50991903
问题
今天在学习进程间通信之-信号signal–linux内核剖析(九)
遇见了一个奇怪的问题
storage size of ‘oldact’ isn’t known
1
1
于是FQ去google之。
分析了好久,终于发现问题的原因了。于是记录下来
发现
测试的代码如下
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <bits/sigaction.h>
int main()
{
struct sigaction act;
return 0;
gcc test.c
按照默认进行编译,无错误
gcc test.c -std=gnu99
和gcc test.c -std=gnu9x
无错
gcc test.c -std=c99
出错
gcc test.c --ansi
出错
原因解析
The following link has a lot of information.
其实说的很明晰了,就是说signal是一个ansi/C99编译器支持的函数,sigaction是后来在POSIX.1-2001中新增的接口,那么由于向前兼容的特性,ansi/c99并不支持sigaction函数接口。
也就是说,大多数操作系统均支持signal,但是却只有部分支持sigaction。
因此编译器在处理的时候,如果你指定了–ansi或者-std=c99的指令后,编译器会认为你要是编译一个标准的C程序,那么就在编译时(准确的来说是预处理阶段)将你不符合C标准的地方舍弃掉,
怎么舍弃呢?当然是通过宏了。
验证
我们知道gcc编译器可以通过-E来进行预处理来生成预处理后的文件。
那么我们现在来验证一下子,我们在生成的预处理文件中,搜索指定的sigaction关键字,看预处理的文件中,有没有该结构体的定义
gcc -E test.c -std=c99 | grep sigaction
gcc -E test.c --ansi | grep sigaction
很明显,我们指定了使用C标准的编译器后,编译器在预处理阶段针对非C标准的接口都屏蔽掉了。
同样我们使用GNU编译器扩展的C编译器进行预处理,看看有什么
gcc -E test.c -std=gnu99 | grep sigaction
gcc -E test.c -std=gnu9x | grep sigaction
好了,我们现在是不是很清楚了
关于具体gcc编译参数的详情,请参见GCC Command-Line Options
我们可以看到–ansi指定使用古老的标准ansiC标准编译,-std=c99则指定使用新的C99标准编译,而gnu99 和gnu9x 则是gcc编译器对C99标准自己的实现
这些的关系是什么呢,
首先标准委员会指定了语言的标准,也就是ansi和后来的C88,C99标准
但是只有标准怎么行,必须有编译器来支持啊,于是各个编译器都开始逐步支持新的标准,同时也就是出现了-std=c89,-stdc99,为了兼容之前的程序,而保留旧的标准–ansi
但是对标准的支持,不可能一下子,只实现了一部分,慢慢再进行扩展,另外由于标准中某些地方可能并不实用,可能需要一些扩展,于是出现了-std=gnu99,现在很多编译器对C的语法都有一些不同的扩展,而这些扩展有些已经加入了新的标准中,有些并未加入或者正在议案加入。
解决
解决方法1
就是我们在编译的过程中编译器的类型,比如-std=gnu99
解决方法2
在#include <signal.h>之后显式添加sigaction的头文件
#include <bits/sigaction.h>
1
1
这样编译器会显式的编译sigaction的定义
但是这种情况下需要注意,#include <bits/sigaction.h> 必须在#include <signal.h>之后
因为signal中会通过#error进行预处理,检查`bits/sigaction.h是否包含,
如果用户没有包含的话,预处理阶段就会报错
#error "Never include <bits/sigaction.h> directly; use <signal.h> instead."
版权声明:本文为博主原创文章 && 转载请著名出处 @ http://blog.csdn.net/gatiemehttps://blog.csdn.net/gatieme/article/details/50991903