linux服务器定时器,Linux服务器定时器处理要注意的问题

今天早上,例行巡查服务器,我用strace命令跟踪服务器进程的时候, 发现有几个服务器进程出现了死锁情况, gdb继续跟进,显示如下:

gdb) bt

#00x00ff9410in__kernel_vsyscall ()

#10x004d593ein__lll_mutex_lock_wait () from/lib/libc.so.6#20x00465b38in_L_lock_14080 () from/lib/libc.so.6#30x00464df4infree () from/lib/libc.so.6#40x006c7691inoperatordelete () from/usr/lib/libstdc++.so.6#50x08059cfbin__gnu_cxx::new_allocator<:_list_node>>::deallocate (this=0x98e0064, __p=0x98e1218)

at/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/ext/new_allocator.h:94#60x08059d20instd::_List_base>::_M_put_node (this=0x98e0064, __p=0x98e1218)

at/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_list.h:320#70x08059d81instd::list>::_M_erase (this=0x98e0064, __position={_M_node=0x98e1218}) at/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_list.h:1150#80x08059db3instd::list>::pop_front (this=0x98e0064)

at/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_list.h:747#90x08059334inCTimerManager::Process (this=0x98e0058) at src/timermanager.cpp:168#100x080597ddinProcess (nSigNo=14) at src/timermanager.cpp:199#11#120x004612bain_int_free () from/lib/libc.so.6#130x00464e00infree () from/lib/libc.so.6#140x006c7691inoperatordelete () from/usr/lib/libstdc++.so.6#150x006a424dinstd::string::_Rep::_M_destroy () from/usr/lib/libstdc++.so.6#160x0069e40finstd::basic_stringbuf, std::allocator>::~basic_stringbuf ()

from/usr/lib/libstdc++.so.6#170x0069fd7finstd::basic_stringstream, std::allocator>::~basic_stringstream ()

from/usr/lib/libstdc++.so.6#180x080524eainCDBMoudle::Insert (this=0x98e6e80, tFixkey=@0xbfe1c6ec) at src/dbmoudle.cpp:59#190x08051718inCConnectionTask::ProcFixContent (this=0x98e6510) at src/connectiontask.cpp:218#200x0805196einCConnectionTask::HandleRead (this=0x98e6510) at src/connectiontask.cpp:86#210x08051a0finCConnectionTask::Handle (this=0x98e6510, nEvent=1) at src/connectiontask.cpp:52#220x080585afinIServer::Run (this=0xbfe1c7e0) at src/server.cpp:133#230x08055328inmain (argc=2, argv=0xbfe1c8b4) at src/main.cpp:19

在#13处,调用free函数, 然后进入与之相关的libc函数调用中.但是, 在这个调用还没有完结之前被定时器管理模块中断, 进入了定时器处理的部分, 在在这个处理中同样调用了free函数, 于是出现了死锁的情况--因为malloc/free函数族不是可重入的, 在这里有一篇相关的文章.

我曾经想在我的服务器代码中尽量减少对象的构造/析构, 但是想了一下, 这个策略不是治本的办法, 这意味着我必须在写代码的时候处处小心, 今天可能在A处出现死锁, 明天可能会在B处出现.而且, 由于使用的是C++, 一些局部对象的构造和析构是不可避免的.

于是, 解决这个问题的思路就改变为:尽量的简单化定时器处理操作.目前我想到的一个策略时, 一个定时器被触发的时候, 置一个标志位, 而不是在在触发的时候调用相应的处理函数, 然后在服务器的主循环中判断是否被置位, 如果是的话再去调用相关的处理函数.

于是, 原来的思路就是:

//该函数在定时器到时的时候被触发voidsignal()

{//定时器处理函数dosomething();

}while(1)

{

服务器主循环;

}

修改之后的思路是:

intviolate g_alarm=0;//该函数在定时器到时的时候被触发voidsignal()

{

g_alarm=1;

}while(1)

{

服务器主循环;if(g_alarm)

{//定时器处理函数dosomething();

g_alarm=0;

}

}

这是大概的模型上面的改变.这是我目前能想到的处理该问题的最好办法, 如果哪位有更好的办法欢迎补充.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值