signal在服务器开发中的简单应用

开发高性能的游戏服务器程序需要用到很多知识,也要注意很多细节,通过不断地积累,将一个一个简单的知识点组合,最终便形成一个高效稳定的游戏服务器。
signal在服务器开发中的简单应用。
Siganl函数用于设置某一个信号的对应动作,如果不设置,执行系统默认处理(通过 man 7 signal 查询),有些结果可能不是我们想要的,有时候需要我们设置。如下是通过man查到的函数声明:
#include <signal.h>
typedef void(*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
第一个参数signum 顾名思义是要设置的信号id,第二个参数是signum指定信号的处理函数,当有该信号触发时,内核自动调用处理函数。参数有两种,一种是指定的宏, SIG_IGN忽略该信号,或者是SIG_DFL恢复系统对该信号的默认处理,还有一种就是我们自定义函数处理。
我们也可以用更加健壮和安全的sigaction函数进行设置,声明如下:
#include<signal.h>
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
第一个参数signum 顾名思义是要设置的信号id;
第二个参数act是指向sigaction结构体的指针,指定了对该信号的处理,可以为NULL,进程会以缺省方式对信号处理;
第三个参数oldact用来获取原来对该信号的处理内存,可以为NULL。


在写程序时有些信号我们希望忽略处理:
SIGPIPE 13信号在向没有读的管道写入数据的时候触发,系统的默认处理是终止进程。
当客户端close了连接,服务器端接着发包,会返回rst错误,如果再发内核会向程序发送SIGPIPE信号,默认处理是终止进程,结果不是我们想要的,通过以下代码可以安全屏蔽SIGPIPE信号。
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sa, NULL);
为了防止僵尸进程的发生,我们需要父进程忽略子进程的退出,交给系统init去回收资源
signal(SIGCHLD, SIG_IGN);
在多线程程序中,我们可以通过pthread_sigmask的掩码设置来屏蔽信号,每个线程都有自己的掩码,当我们需要子线程也屏蔽某些信号时,在主线程中对sigmask进行设置后,生成的子线程将继承主线程的掩码,子线程也屏蔽了这些信号。
多线程服务器程序要屏蔽中断信号,通过以下代码实现:
sigset_t sigmask;
sigemptyset(&sigmask);
sigaddset(&sigmask, SIGINT);//中断信号,ctrl +c触发该信号
pthread_sigmask(SIG_BLOCK, & sigmask, NULL); /*子线程将继承主线程的掩码,子线程收不到SIGINT信号*/
信号可以用来生成崩溃日志,在程序开始时,对
SIGILL (4 非法指令,如堆栈溢出,执行数据段等), SIGABRT (6 进程停止运行调用abort函数), SIGFPE  (8浮点异常 ,运算错误,如除0,溢出等), SIGKILL (9 停止进程(此信号不能被忽略或捕获)), SIGSEGV (11 无效地内存访问), SIGTERM (15 终止进程信号),SIGXFSZ(25,25,31超出文件大小资源限制) 对这些信号进行监听,在这些信号触发时,系统自动调用我们自定义的sighandler函数,在这个函数中,我们可以将堆栈信息写入崩溃日志文件,查找程序崩溃问题。获取当前线程调用的堆栈可以用backtrace,backtrace_symbols,backtrace_symbols_fd 几个函数 。头文件execinfo.h
int backtrace (void **buffer, int size); 
char **backtrace_symbols (void *const *buffer, int size); 
void backtrace_symbols_fd (void *const *buffer, int size, int fd);  
将崩溃时的堆栈信息写入日志文件,通过gdb来定位导致崩溃的位置。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值