我在C ++中实现了一个WebSocket处理程序,我需要偶尔发送一次ping消息。但是,我不希望每个套接字/一个全局轮询线程启动一个线程,该线程只调用ping函数,而是使用某些OS功能来调用我的计时器函数。在Windows上,有SetTimer
,但这需要一个有效的消息循环(我没有。)在Linux上有timer_create
,看起来更好。
是否有一些可移植的,低开销的方法来定期调用一个函数,理想情况下是一些自定义上下文?即类似于settimer (const int millisecond, const void* context, void (*callback)(const void*))
?
[编辑]只是为了让这一点更加清晰:我不想管理其他线程。在Windows上,我想在系统线程池上使用CreateThreadpoolTimer
可以解决问题,但我很想知道是否有更简单的解决方案以及如何将其移植到Linux上。
答案 0 :(得分:1)
答案 1 :(得分:0)
如果您使用套接字,则可以使用select,等待套接字事件超时, 并在此循环中计算时间并在适当的时间内调用回调。
答案 2 :(得分:0)
如果您正在寻找一个不需要额外线程的计时器,那么让您透明地完成工作,然后通过先发制人地中断您的应用程序,在同一个线程中的适当时间调用计时器功能,然后就没有了这样便携的东西。
第一个原因是它非常危险。这就像用完全没有同步编写多线程应用程序。第二个原因是在多线程应用程序中具有良好的语义是非常困难的。哪个线程应该执行定时器回调?
如果您正在编写Web套接字处理程序,那么您可能已经在编写基于select()
的循环。如果是这样,那么您可以使用短暂超时的select()
并检查需要ping每个对等方的不同连接。
答案 3 :(得分:0)
每当有异步事件时,都应该有一个事件循环。这不需要是一些系统默认的,如Windows的消息循环。你可以创建自己的。但你应该使用它。
关于基于事件的编程的重点在于,您正在解耦代码处理,以便根据这些异步事件处理定义明确的函数片段。如果没有事件循环,您就会谴责自己交错获取输入的代码并根据定义不明确的“状态”生成输出,这些状态只是程序代码的片段。
如果没有使用基于事件的设计明确定义的状态分离,代码很快就会变得无法管理。因为代码在执行输入任务的过程中暂停,所以对象的生命周期不会跨越整个过程范围,并且您将开始在访问基于事件创建或销毁的对象的各个位置编写if(nullptr == xx)。由于您在每个输入点都有不同的事件而且没有抽象,因此调度变得更加复杂。
但是,只需使用事件循环并调度到状态机,就可以降低处理程序(O(n)处理程序与具有n种事件和m种状态的O(mn)分支语句)的基本管理的处理复杂性。您可以解除处理,但仍允许根据状态更改功能。但是现在这些状态是使用状态类定义的。如果产品的要求发生变化,可以添加新的状态。
我只是说,停止尝试避免事件循环。这是一个非常重要的软件模式,所有这些都与生成专业,可重用,可扩展的代码有关。使用Boost.ASIO或其他一些框架来实现跨平台功能。不要因为你认为这样做不那么努力而养成做错的习惯。最后,即使它不是一个需要长期维护的专业项目,你也希望练习使你的代码专业化,这样你就可以用你的技能做一些事情。