FreeBSD下accept函数不能被信号中断的问题
本帖最后由 happy_fish100 于 2010-08-09 18:48 编辑
FastDFS 2.0改造中,kill 服务进程时,如kill fdfs_storaged,服务进程在Linux可以正常退出,在FreeBSD下会一直运行。
经过调试,发现FreeBSD下accept这个堵塞式的系统调用没有被kill中断的缘故。
解决方法,当使用kill -TERM或者kill -INT杀掉进程,当程序收到退出信号时,连接一下自己即可结束堵塞的accept调用。
因为在Linux中是正常的,所以代码中采用了定时器,1秒后才发出连接自己的动作。代码如下:
static bool bAcceptEndFlag = false; //accept normal end flag
int main(int argc, char *argv[])
{
...
bAcceptEndFlag = false;
storage_accept_loop(sock); //循环accept
bAcceptEndFlag = true;
...
}
//定时器处理函数
static void sigAlarmHandler(int sig)
{
TrackerServerInfo server;
if (bAcceptEndFlag)
{
return;
}
logDebug("file: "__FILE__", line: %d, "
"signal server to quit...", __LINE__);
if (*g_bind_addr != '')
{
strcpy(server.ip_addr, g_bind_addr);
}
else
{
strcpy(server.ip_addr, "127.0.0.1");
}
server.port = g_server_port;
server.sock = -1;
if (tracker_connect_server_ex(&server, 1) != 0)
{
return;
}
fdfs_quit(&server);
tracker_disconnect_server(&server);
logDebug("file: "__FILE__", line: %d, "
"signal server to quit done", __LINE__);
}
//退出信号处理函数
static void sigQuitHandler(int sig)
{
if (!bTerminateFlag)
{
set_timer(1, 1, sigAlarmHandler);
bTerminateFlag = true;
g_continue_flag = false;
logCrit("file: "__FILE__", line: %d, "
"catch signal %d, program exiting...",
__LINE__, sig);
}
}
//设置定时器
int set_timer(const int first_remain_seconds, const int interval,
void (*sighandler)(int))
{
struct itimerval value;
struct sigaction act;
memset(&act, 0, sizeof(act));
sigemptyset(&act.sa_mask);
act.sa_handler = sighandler;
if(sigaction(SIGALRM, &act, NULL) < 0)
{
logError("file: "__FILE__", line: %d, "
"call sigaction fail, errno: %d, error info: %s",
__LINE__, errno, strerror(errno));
return errno != 0 ? errno : EINVAL;
}
memset(&value, 0, sizeof(value));
value.it_interval.tv_sec = interval;
value.it_value.tv_sec = first_remain_seconds;
if (setitimer(ITIMER_REAL, &value, NULL) < 0)
{
logError("file: "__FILE__", line: %d, "
"call setitimer fail, errno: %d, error info: %s",
__LINE__, errno, strerror(errno));
return errno != 0 ? errno : EINVAL;
}
return 0;
}
以上是我的解决办法。看看大家有没有更好的解决方法,呵呵。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论