zoukankan      html  css  js  c++  java
  • 将Linux的信号量sem_t封装成事件对象

    将信号量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事件对象,同步线程中的测试代码对其进行测试。其结果是相同的。
  • 相关阅读:
    Stack堆栈的数据结构
    反坦克导弹相关网页
    Java 执行jar文件出现版本错误信息
    Python3 数字保留后几位
    Python3: Windows系统上同时安装Python2和Python3
    Linux 搭建FTP
    DBCP、c3p0、Druid三大连接池区别
    Sybase 存储过程中IF的用法
    Confluence5.8部分空间名称显示为问号的解决方案
    Mysql 更改编码方式
  • 原文地址:https://www.cnblogs.com/lidabo/p/14745339.html
Copyright © 2011-2022 走看看