C++实现一个简易版的事件(Event)的示例代码

 更新时间:2022年11月15日 11:49:32   作者:程序员~彭国庆  
之前在 windows系统中开发应用时, 遇到需要进行线程同步的时候几乎都是使用的事件内核对象 Event。本文为大家整理了C++实现一个简易版的事件(Event)的相关资料,需要的可以参考一下

一、前言

利用 WaitForSingleObject 检查内核对象的状态来进行实现。后来随着需要开发跨平台的程序后这种方式就不能使用了, 毕竟这是 windows 专属。 POCO 库在 windows之外的系统选择利用 pthread 线程库库来实现 Event, pthread 毕竟不在C++标准库里面,假设要使用的话需要单独配置。所以本文就利用 C++11之后的标准库内容来实现一个事件类, 方便使用。

本文代码地址:https://github.com/pengguoqing/samples_code

二、实现

2.1 需要具备的功能

①支持多线程

②可以等待一定时间

2.2 代码实现

一共提供四个对外接口, 分别如下:

//设置事件有信号
    inline void SetEvent()   const;
    
    //重置事件为无信号
    inline void ResetEvent() const;
    
    //持续等待直到事件有信号, 如果是 Auto 模式则必须等待到该线程能拿到状态
    inline void Wait()       const;    
    
    //等待事件一定时间, 时间范围内事件有信号则返回 true,否则返回 false
    template <typename Rep, typename Period>
    inline bool tryWait(const std::chrono::duration<Rep, Period>& duratio) const;

类内部再对具体的实现进行一下封装

struct EventImpl
	{
		explicit EventImpl(Mode mode, bool initState);
		~EventImpl() = default;
		inline void  Set();
		inline void  Reset();
		inline void  Wait();

		template <typename Rep, typename Period>
		inline bool Wait_for(const std::chrono::duration<Rep, Period>& duration);

		std::mutex				m_mutex;
		std::condition_variable m_condi;
		bool					m_signal;
		const Mode				m_mode;
	};

使用 unique_ptr 对 EventImpl 资源进行管理:

const std::shared_ptr<EventImpl> m_event;

因为没有裸露的指针资源,移动和拷贝函数就直接全部使用编译器默认的

explicit CXEvent(Mode mode = Mode::Auto, bool initstate = false);
~CXEvent() = default;

三、测试

测试用一个事件实例来实现两个线程的同步测试, 键盘输入字符 ‘s’ 触发一次事件, 每个线程 Wait() 两次事件后,再测试一下 tryWait() 时间。代码如下:

using namespace std;

static CXEvent kEvent;
static constexpr int testCnt = 3;

TestEventFunc1(const CXEvent& refEvent)
{
    for (int i=0; i< testCnt; i++)
    {
        
		if (i == testCnt-1)
		{
			auto begin = chrono::high_resolution_clock::now();
			kEvent.tryWait(5000ms);
			auto end = chrono::high_resolution_clock::now();
			auto duration = chrono::duration_cast<chrono::microseconds>(end - begin);
			cout << "TestEventFunc1"<<"tryWait time:"<< duration.count() << endl;
		}
		else
		{
			kEvent.Wait();
			cout << "TestEventFunc1 Wait" << endl;
		}
       
    }

}
TestEventFunc2(const CXEvent& refEvent)
{
	for (int i=0; i<testCnt; i++)
	{
		if (i == testCnt-1)
		{
			auto begin = chrono::high_resolution_clock::now();
			kEvent.tryWait(5000ms);
			auto end = chrono::high_resolution_clock::now();
			auto duration = chrono::duration_cast<chrono::microseconds>(end - begin);
			cout << "TestEventFunc2" << "tryWait time:"<< duration.count()<< endl;
		}
		else
		{
			kEvent.Wait();
			cout << "TestEventFunc2 Wait" << endl;
		}
		
	}
}

int main()
{
   	CXEvent refEvent1(kEvent);
	CXEvent refEvent2(kEvent);
    std::thread testTh1(TestEventFunc1, refEvent1);
    std::thread testTh2(TestEventFunc2, refEvent2);

	int cinCnt{0};
	char inputCmd {'R'};
	cin.get(inputCmd);
	while ('q'!=inputCmd && cinCnt<testCnt*2)
	{
		if ('s' == inputCmd)
		{
			kEvent.SetEvent();
			cinCnt++;
		}
		cin.get(inputCmd);
	}

   
	if (testTh1.joinable())
	{
		testTh1.join();
	}

	if (testTh2.joinable())
	{
		testTh2.join();
	}

	std::cout << "test set event and wait_for event\n";
}

期望结果是每输入一次 ‘s’ 回车后,TestEventFunc1或者TestEventFunc2线程函数中的循环体就会被执行一次,每个循环体执行两次后等待 5 秒线程就退出,再输入‘q’ 退出程序。实际运行结果如下:

符合预期。

到此这篇关于C++实现一个简易版的事件(Event)的示例代码的文章就介绍到这了,更多相关C++事件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++内存管理之简易内存池的实现

    C++内存管理之简易内存池的实现

    大家好,本篇文章主要讲的是C++内存管理之简易内存池的实现,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2021-12-12
  • C++实现二叉树遍历序列的求解方法

    C++实现二叉树遍历序列的求解方法

    这篇文章主要介绍了C++实现二叉树遍历序列的求解方法,需要的朋友可以参考下
    2014-08-08
  • C语言之详解静态变量static

    C语言之详解静态变量static

    在C语言中static是用来修饰变量和函数的,这篇文章详细介绍了static主要作用,文章中有详细的代码实例,需要的朋友可以参考阅读
    2023-04-04
  • c语言 两字符串交叉合并实例

    c语言 两字符串交叉合并实例

    今天小编就为大家分享一篇c语言 两字符串交叉合并实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • 一篇文章教你如何用C语言实现strcpy和strlen

    一篇文章教你如何用C语言实现strcpy和strlen

    这篇文章主要为大家介绍了C语言实现strcpy和strlen的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • C++ primer类的基础精讲

    C++ primer类的基础精讲

    C++类,是指系统在第一次在程序中遇到一个类时为这个类建立它的所有类变量的拷贝 - 这个类的所有实例共享它的类变量
    2022-07-07
  • c++中引用作为形参的使用方法以及作用

    c++中引用作为形参的使用方法以及作用

    这篇文章主要给大家介绍了关于c++中引用作为形参的使用方法以及作用的相关资料,引用是地址传值,作为引用的形参数值被修改的同时,也修改了对应实参的值,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-11-11
  • C++ vector的用法小结

    C++ vector的用法小结

    这篇文章主要介绍了c++中,vector是一个十分有用的容器,下面对这个容器做一下总结
    2013-12-12
  • 详解c++实现信号槽

    详解c++实现信号槽

    这篇文章主要为大家介绍了c++实现信号槽,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-12-12
  • C语言代码中调用C++代码的方法示例

    C语言代码中调用C++代码的方法示例

    这篇文章主要介绍了C语言代码中调用C++代码的方法示例,文中也介绍了C++代码调用C代码的方法,有需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-02-02

最新评论