概述
目录
代码结构如下:
代码解析:
check tread:
receive tread:
send tread:
完整代码工程下载:
编译代码方式:
功能实现:可以检测 进程是否 live 或者 僵死,然后根据具体状态,发signal 处理被检测的进程
demo 有两个进程 一个是 server 另一个是 client (可以有多个)(send && receive)
代码结构如下:
├── bin
├── include
│ ├── heartbeat.h
│ ├── Log.h
│ └── udpnet.h
├── Makefile
├── make.sh
├── obj
└── src
├── heartbeat.cpp
├── Log.cpp
├── recv
│ └── heartbeatMonitor.cpp
├── send
│ └── heartbeatMonitor_send.cpp
└── udpnet.cpp
代码解析:
两个进程,主要有3个线程来实现:send tread receive tread check thread
check tread:
void* HeartbeatMonitor::checkThread( void* param )
{
const int LOST_LIMIT = 5;
static int call_cnt = 0;
HeartbeatMonitor* monitor = (HeartbeatMonitor*)param;
HeartbeartStatistic &statistic = monitor->statistic; //使用 引用调用 HeartbeatMonitor
int pkg_cnt = 0;
bool err_found = false;
Heartbeat new_heartbeat;
HeartbeatChecker checker;
hb_usleep(HEARTBEAT_CYCLE_MS * 1000); // 3000 ms
while(1)
{
int &pkg_lost_cnt = checker.pkg_lost_cnt;
if (monitor->pkg_cnt == pkg_cnt) //丢包判断
{
pkg_lost_cnt++;
statistic.pkg_lost_cnt++;
hbprintf(DEBUG_LOG, DBG_HEAD " YL Pkg lost for %d times.", pkg_lost_cnt);
if (LOST_LIMIT < pkg_lost_cnt)
{
checker.recover();
statistic.pkg_lost_kill_cnt++;
}
goto LOOP_DELAY;
}
else
{
pkg_cnt = monitor->pkg_cnt;
pkg_lost_cnt = 0;
}
new_heartbeat = monitor->getHeartbeat();
err_found = false;
for (int i = 0; i < HEARTBEAT_COUNTER_NUM; ++i) //检测不同模块的进程的 状态counter
{
if (new_heartbeat.counter[i] == checker.heartbeat.counter[i])
{
err_found = true;
break;
}
}
if (err_found)
{
//new_heartbeat.showContent(DBG_HEAD);
}
for (int i = 0; i < HEARTBEAT_COUNTER_NUM; ++i)
{
int &lost_cnt = checker.lost_cnt[i];
if (new_heartbeat.counter[i] != checker.heartbeat.counter[i])
{
lost_cnt++;
statistic.lost_cnt.counter[i]++;
hbprintf(DEBUG_LOG, DBG_HEAD ""%s" lost for %d times.", Heartbeat::counter_name[i], lost_cnt);
if (LOST_LIMIT < lost_cnt)
{
checker.recover(); //丢包 超过次数后执行 操作
statistic.kill_cnt.counter[i]++;
goto LOOP_DELAY;
}
}
else
{
lost_cnt = 0;
}
}
checker.heartbeat = new_heartbeat;
statistic.last_heart = new_heartbeat;
LOOP_DELAY:
++call_cnt;
if (call_cnt % HEARTBEAT_PRINT_CYCLE == 0)
{
statistic.showContent("HeartbeatMonitor");
}
hb_usleep(HEARTBEAT_CYCLE_MS * 1000); // 3000 ms
}
return (void *)0;
}
receive tread:
/* static */ void* HeartbeatMonitor::recvThread( void* param )
{
#define DBG_HEAD "[Recv] "
bool ret = true;
UINT32 peer_ip; //lo: 127.0.0.1 Loopback address
int peer_port;
double heartbeat_cycle_sec = 1.0 * HEARTBEAT_CYCLE_MS / 1000;
HeartbeatMonitor* monitor = (HeartbeatMonitor*)param;
HeartbeartStatistic &statistic = monitor->statistic;
while(1)
{
ret = monitor->netAdp.NetRecv(monitor->recv_buff, monitor->recv_size, heartbeat_cycle_sec, &peer_ip, &peer_port);
if (ret == false)
{
if (monitor->recv_size == 0)
{
hbprintf(DEBUG_LOG, DBG_HEAD "Time out at NetRecv.");
statistic.timeout_cnt++;
}
else
{
hbprintf(DEBUG_LOG, DBG_HEAD "ERROR at NetRecv.");
statistic.err_cnt++;
}
continue;
}
//hbprintf(DEBUG_LOG, DBG_HEAD "Hearbeat recv ok.");
monitor->pkg_cnt++;
statistic.ok_cnt++;
monitor->parseHeartbeatPkg();
}
return (void *)0;
#undef DBG_HEAD
}
send tread:
/* static */ void* HeartbeatSender::sendThread( void* param )
{
#define DBG_HEAD "[ YL -- Send] "
static int call_cnt = 0;
int iRet = true;
bool ret = true;
HeartbeatSender* sender = (HeartbeatSender*)param;
HeartbeartStatistic &statistic = sender->statistic;
while(1)
{
if (HeartbeatPkgUT_ON())
{
goto CYCLE_DELEY;
}
sender->generateHeartbeatPkg();
hbprintf(DEBUG_LOG," YL -- dest_ip = %d ,dest_port = %d,sender->send_size =%d , sender->send_buff =%s",sender->dest_ip,sender->dest_port,sender->send_size,sender->send_buff);
ret = sender->netAdp.NetSend(sender->dest_ip,
sender->dest_port,
sender->send_buff,
sender->send_size,
&iRet);
if (ret == false)
{
if (iRet == 0)
{
hbprintf(DEBUG_LOG, DBG_HEAD "Time out at NetSend.");
statistic.timeout_cnt++;
}
else
{
hbprintf(DEBUG_LOG, DBG_HEAD "ERROR at NetSend.");
statistic.err_cnt++;
}
goto CYCLE_DELEY;
}
// hbprintf(DEBUG_LOG, DBG_HEAD "Hearbeat send ok.");
statistic.last_heart = sender->getHeartbeat();
statistic.ok_cnt++;
CYCLE_DELEY:
++call_cnt;
if (call_cnt % HEARTBEAT_PRINT_CYCLE == 0)
{
statistic.showContent("HeartbeatSender");
}
hb_usleep(HEARTBEAT_CYCLE_MS * 1000); // 3000 ms
}
return (void *)0;
#undef DBG_HEAD
}
完整代码工程下载:
To click on:core download
编译代码方式:
make all 即可以编译出搜有模块
有兴趣的可以修改 Makefile和代码 编译多个 receive 端
最后
以上就是娇气奇异果为你收集整理的c++ 进程间心跳检测--socket (UDP)的全部内容,希望文章能够帮你解决c++ 进程间心跳检测--socket (UDP)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复