智能指针实现代码--定时器实例

本文详细介绍了如何使用智能指针实现一个高效、可靠的定时器类,包括注册、注销定时器以及定时器的运行机制。通过模板类的设计,使得定时器能够灵活应用于不同场景,提高代码复用性和可维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

话不多说,直接看实现源码。

// 单线程模型,自增减没有互斥处理
class SingleThread
{
public:
	static long _Increment(long* p){ return ++(*p); }
	static long _Decrement(long* p){ return --(*p); }

};
// 计数器类
template<class ThreadModel = SingleThread>
class Counter
{
public:
	Counter() : _m_val(0){}
	long _Increment(){ return ThreadModel::_Increment(&_m_val); }
	long _Decrement(){ return ThreadModel::_Decrement(&_m_val); }
	long _GetCount(){ return _m_val; }
private:
	long _m_val;
};

template<class T>
class _MemPtr : public T
{
public:
	_MemPtr(){}
private:
	long _Increment();
	long _Decrement();
};
// 普通对象智能指针模板类,参数T必须从Counter继承
template<class T>
class MemPtr
{
public:
	MemPtr() : m_p(NULL){}
	MemPtr(T* p) : m_p(p){ AddRef(); }	// ,
	MemPtr(const MemPtr<T>& s) : m_p(s.m_p){ AddRef(); }
	~MemPtr(){ Release(); }
	MemPtr<T>& operator=(const MemPtr<T>& r)
	{
		if(m_p != r.m_p){ Release(); m_p = r.m_p; AddRef(); }
		return *this;
	}
	operator T*() { return m_p; }
	_MemPtr<T>* operator->() const { return (_MemPtr<T>*)m_p; }
	bool operator==(const MemPtr<T>& r) const{ return m_p == r.m_p; }
	bool operator!=(const MemPtr<T>& r) const{ return m_p != r.m_p; }
	bool operator!() const{ return !m_p; }
	operator bool() const{ return m_p != NULL; }
	void Attach(T* p){ Release(); m_p = p; }
	T* Detach(){ T* p = m_p; m_p = NULL; return p; }
	void Release()
	{
		if(m_p)
		{
			if(m_p->_Decrement() == 0){ delete m_p; }
			m_p = NULL;
		}
	}
	T* Copy() { AddRef(); return m_p; }
	long GetRef() const		// Used for debugging
	{
		if(m_p) return m_p->_GetCount(); return -1;
	}
	T* m_p;					// 请勿直接改写此变量
protected:
	void AddRef(){ if(m_p) m_p->_Increment(); }
};


以下是基于智能指针的定时器简单实现:

typedef unsigned long ULONG;
typedef unsigned __int64 UINT64;


class CTimer
{
public:
	CTimer(){}
	~CTimer(){}
public:
	void RegisterTimer( UINT64 id, ULONG period, UINT64 times );
	void UnRegisterTimer( UINT64 id );
	void RunTimer();
private:
	struct _TimerInfo : public Counter<>
	{
		ULONG ulLastTime;
		ULONG ulNextTime;
		ULONG ulPeriod;
		UINT64 uiTimes;
		_TimerInfo():uiTimes(0),ulLastTime(0),ulNextTime(0),ulPeriod(0){}
	};
	typedef map< UINT64, SmartPointer<_TimerInfo> >_TimerMap;
	_TimerMap m_timer;

	static UINT64 m_id;

};

UINT64 CTimer::m_id = 0;

void CTimer::RegisterTimer( UINT64 id, ULONG period, UINT64 times )
{
	SmartPointer<_TimerInfo> timer(new _TimerInfo);
	timer->ulLastTime = ::GetTickCount();
	timer->ulNextTime = timer.m_p->ulLastTime + period;
	timer->ulPeriod = period;
	timer->uiTimes = times;
	//m_id += 1;
	m_timer.insert(make_pair(id, timer));
}

void CTimer::UnRegisterTimer(UINT64 id)
{
	_TimerMap::iterator iter = m_timer.find(id);
	if( iter != m_timer.end())
	{
		m_timer.erase(id);
	}
}

void CTimer::RunTimer()
{
	while( 1 )
	{
		_TimerMap::iterator iter = m_timer.begin();
		for( ;iter != m_timer.end(); ++iter)
		{
			ULONG now = ::GetTickCount();
			if( now >= iter->second->ulNextTime  )
			{
				if( m_id == 3 ) break;
				printf("timer id is:%d\n",iter->first);
				iter->second->ulLastTime = now;
				iter->second->ulNextTime = now + iter->second->ulPeriod;
				m_id += 1;
			}
		}
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	CTimer timer;
	//timer.RegisterTimer(1, 1000, 5);
	timer.RegisterTimer(2, 2000, 3);
	timer.RunTimer();
	
	return 0;
}



### FreeRTOS定时器中断实现使用 #### 创建定时器 在FreeRTOS中,创建一个定时器可以通过`xTimerCreate()`函数完成。此函数允许定义定时器名称、周期长度、是否自动重载(即单次或周期模式)、关联的ID以及超时时应调用的回调函数[^4]。 ```c TimerHandle_t xTimer; const TickType_t xTimerPeriod = pdMS_TO_TICKS(1000); // 设置为1秒 UBaseType_t uxAutoReload = pdTRUE; // 使用pdFALSE表示单次模式 void *pvTimerID = ( void * ) 0; // 可选参数,用于传递给回调函数的数据指针 TimerCallbackFunction_t pxCallbackFunction = vTimerCallback; xTimer = xTimerCreate( "OneSecondTimer", /* 名字 */ xTimerPeriod, /* 超时期限 */ uxAutoReload, /* 自动重启标志位 */ pvTimerID, /* ID */ pxCallbackFunction /* 回调函数 */ ); ``` #### 启动和停止定时器 一旦创建了定时器实例,则可以利用`xTimerStart()`来激活它;如果需要在一个中断上下文中启动定时器,则应该使用`xTimerStartFromISR()`版本。同样地,存在对应的停止单个定时器的方法——`xTimerStop()`及其从中断环境调用的形式`xTimerStopFromISR()`。 #### 处理定时器溢出 对于硬件定时器而言,在达到设定的时间间隔后会产生一个中断请求IRQ,随后程序跳转至相应的中断服务子程序(ISR),在这里执行预设的操作逻辑。而对于软件定时器来说,当计数结束时并不会直接引发真正的硬件中断,而是由内核安排特定的任务去检查是否有任何到期的定时器,并据此触发各自的回调函数[^3]。 #### 中断管理实践案例 为了更好地理解如何管理和配置这些特性,考虑这样一个例子:有两个不同优先级级别的定时器被用来每隔一秒向控制台输出消息。通过调整全局中断使能状态(`vTaskSuspendAll()/xTaskResumeAll()`)可观察到预期的行为变化—关闭期间不会有任何新消息显示出来,而恢复之后又恢复正常运作[^5]。 #### 定时器工作模式对比 值得注意的是,FreeRTOS支持两种主要类型的定时器行为: - **单次模式**:在这种情况下,每当指定的一段时间过去以后只会运行一次预先注册好的处理例程,接着便处于等待下一轮的手动唤醒之中; - **周期模式**:相比之下更为常见也更实用的方式是让定时器不断重复相同的动作直至显式销毁为止。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值