linux之软看门狗的实现

//softwareWdt.h
/*
*功能:  监测各线程间的运行状态(软看门狗)
*
*作者:JDSH
*
*时间:2015-01-15 22:20
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "Typedef.h"


#define REQUEST_WDT_MAX_NUM	20

class CSoftwareWdt 
{
private:
	bool m_fReqWdtFlg[REQUEST_WDT_MAX_NUM];	//=true 已经申请ID成功,=false反之

	WORD m_wWdtTimeout[REQUEST_WDT_MAX_NUM];

	WORD m_wWdtCount[REQUEST_WDT_MAX_NUM];

public:
	CSoftwareWdt();

	~CSoftwareWdt();

	int RequestSoftwareWdtID(const char *cThreadName, WORD wTimeout);	

	bool ReleaseSoftwareWdtID(const char *cThreadName, WORD wTimeout);

	bool KeepSoftwareWdtAlive(WORD wWdtId);

	void MontiorWdtRunState();
};

////////////////////////////////////////////
#include "SoftwareWdt.h"

CSoftwareWdt::CSoftwareWdt()
{
	BYTE bId;

	for (bId = 0; bId < REQUEST_WDT_MAX_NUM; bId++)
		m_fReqWdtFlg[bId] = false;
	memset(m_wWdtTimeout, 0x00, sizeof(m_wWdtTimeout));
	memset(m_wWdtCount, 0x00, sizeof(m_wWdtCount));
}

CSoftwareWdt::~CSoftwareWdt()
{
	;
}

/*
* 功能:申请软件狗的ID
* 返回:申请失败返回-1,成功返回申请到ID
*
*/
int CSoftwareWdt::RequestSoftwareWdtID(const char *cThreadName, WORD wTimeout)
{
	BYTE bId;
	int iRet = -1;

	for (bId = 0; bId < REQUEST_WDT_MAX_NUM; bId++)
	{
		if (m_fReqWdtFlg[bId] == false)	//等于0、表示该ID还没有被申请过,可以使用
		{
			m_wWdtTimeout[bId] = wTimeout;
			m_wWdtCount[bId] = 0;
			m_fReqWdtFlg[bId] = true;
			printf("The thread %s request ID=%d successful. Timeout=%d\n", 
				cThreadName, bId, wTimeout);
			return bId;
		}
	}

	return iRet;
}

bool CSoftwareWdt::ReleaseSoftwareWdtID(const char *cThreadName, WORD wWdtId)
{
	bool fRet = false;
	
	if (wWdtId > REQUEST_WDT_MAX_NUM)
	{
		printf("The thread %s ID=%d is over MAX ID=%d\n", 
			cThreadName, wWdtId, REQUEST_WDT_MAX_NUM);
		return false;
	}

	if (m_fReqWdtFlg[wWdtId] != 0)
	{
		fRet = true;
		m_fReqWdtFlg[wWdtId] = false;
		m_wWdtTimeout[wWdtId] = 0;
		m_wWdtCount[wWdtId] = 0;
		printf("Release thread %s ID=%d\n", cThreadName, wWdtId);
	}	

	return fRet;
}

bool CSoftwareWdt::KeepSoftwareWdtAlive(WORD wWdtId)
{
	if (wWdtId > REQUEST_WDT_MAX_NUM)
		return -1;

	printf("Keep software Wdt Id=%d\n", wWdtId);
	m_wWdtCount[wWdtId] =0;

	return true;
}

void CSoftwareWdt::MontiorWdtRunState()
{
	BYTE bId;

	for (bId = 0; bId < REQUEST_WDT_MAX_NUM; bId++)
	{
		if (m_fReqWdtFlg[bId])
		{
			if (m_wWdtCount[bId]++ > m_wWdtTimeout[bId])
			{
				printf("The Wdt ID=%d is timeout\n", bId);
				system("reboot");
			}
		}
	}
}

CSoftwareWdt *g_CsoftwareWdt;

int main(int argc, char *argv[])
{
	const char *sThreadName[10] = {"One", "Two", "Three", "Four", "Five", 
				 "Six", "Seven", "Eight", "Nine", "Ten"};
	WORD wTimeout = 30;
	BYTE bId =0;
	
	printf("\n\n\n");
	printf("*********************************************\n");
	printf("**************Software wdt Test**************\n");
	printf("*********************************************\n");
	printf("\n");
	
	g_CsoftwareWdt = new CSoftwareWdt();
	
	for (bId = 0; bId < 10; bId++)
	{
		g_CsoftwareWdt->RequestSoftwareWdtID(sThreadName[bId], wTimeout);
	}

	bId = 0;
	while (1)
	{
		g_CsoftwareWdt->MontiorWdtRunState();
		sleep(1);
		g_CsoftwareWdt->KeepSoftwareWdtAlive(bId);
		bId++;
		if (bId > 10)
			bId = 0;
	}

	delete g_CsoftwareWdt;
}


说明:本部分的功能是实现一个软看门狗,用于监测各个线程的运行状态,使用时必须先申请看门狗线程的ID,为了合理的运用软看门狗的资源,线程退出时必须释放看门狗,某个线程超时,将通过调试信息打印超时线程,并最终唤起系统重启,注意这个软看门狗与硬件看门狗的区别。此程序原创,转载请指明出处,如存在缺陷,欢迎指正!

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。