DoubleLi

qq: 517712484 wx: ldbgliet

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  4737 随笔 :: 2 文章 :: 542 评论 :: 1615万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

将信号量sem_t相关的一组API封装成Win32平台上的事件对象类之后,在Linux平台上就可以像使用事件对象那样,方便地进行线程同步了。

class CEventImpl
{
protected:
	
	/*
	 创建匿名信号量
	`bAutoReset  true   人工重置
				 false  自动重置
	*/
	CEventImpl(bool manualReset);		
	
	/*
	 注销信号量
	*/
	~CEventImpl();
 
	/*
	 将当前事件对象设置为有信号状态
	 若自动重置,则等待该事件对象的所有线程只有一个可被调度
	 若人工重置,则等待该事件对象的所有线程变为可被调度
	*/
	void SetImpl();
 
	/*
	 以当前事件对象,阻塞线程,将其永远挂起
	 直到事件对象被设置为有信号状态
	*/
	bool WaitImpl();
 
	/*
	 以当前事件对象,阻塞线程,将其挂起指定时间间隔
	 之后线程自动恢复可调度
	*/
	bool WaitImpl(long milliseconds);
 
	/*
	 将当前事件对象设置为无信号状态
	*/
	void ResetImpl();
 
private:
	bool        m_manual;
	sem_t		m_event;
};
 
inline void CEventImpl::SetImpl()
{
	int ret = sem_post(&m_event);
	if ( 0 != ret )
	{
		cout<<"cannot signal event"<<endl;
	}
}
 
inline void CEventImpl::ResetImpl()
{
	int sval = 0;
	do 
	{
		sem_trywait(&m_event);
		sem_getvalue(&m_event, &sval);
	} while(sval > 0);
}


CEventImpl::CEventImpl(bool manualReset): m_manual(manualReset)
{
	unsigned int nValue = 0; //初始化为无信号
	int ret = sem_init(&m_event, 0, nValue);
	if ( 0 != ret )
	{
		cout<<"sem_init failed"<<endl; 
	}
}
 
CEventImpl::~CEventImpl()
{
	sem_destroy(&m_event);
}
 
bool CEventImpl::WaitImpl()
{
	int ret = sem_wait(&m_event);
	if ( 0 != ret )
	{
		cout<<"CEventImpl::WaitImpl sem_wait failed"<<endl; 
	}
 
	if ( m_manual )
	{
		sem_post(&m_event);
	}
 
	return true;
}
 
bool CEventImpl::WaitImpl(long milliseconds)
{
	if ( 0 == milliseconds )
	{
		int ret = sem_trywait(&m_event);
		if ( 0 == ret )
		{
			if ( m_manual )
			{
				sem_post(&m_event);
			}
		}
	}
	else
	{
		int roopMax = milliseconds/10;
		do 
		{
			usleep(10*1000);
			int ret = sem_trywait(&m_event);
			if ( 0 == ret )
			{
				if ( m_manual )
				{
					sem_post(&m_event);
				}
 
				break;
			}
 
			roopMax--;
		} while( roopMax > 0 );
	}
 
	return true;
}


类CEventImpl 可以使用Linux平台用C++实现事件对象,同步线程或用C++实现Win32事件对象,同步线程中的测试代码对其进行测试。其结果是相同的。
posted on   DoubleLi  阅读(173)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2018-05-08 Car-eye-http-flv-module 实现nginx-rtmp-mudule HTTP方式的FLV直播功能
点击右上角即可分享
微信分享提示