如何以线程安全的方式取消在 Solace 上下文中注册的定时器?
How to cancel timers registered on a Solace context in a thread-safe way?
情况
我正在使用 Solace C API。
我想关联一个状态对象(在我的例子中是一个 C++ 对象,但对于 C API 它只是 void*
用户数据)当定时器触发并且 Solace 调用我的定时器回调例程时.我用 Solace API 调用 solClient_context_startTimer
.
注册了我的计时器
假设我还想从另一个线程取消定时器,知道 solClient_context_startTimer
返回的定时器 ID。我的问题是我还想取消分配状态对象。因此,如果计时器可以从上下文线程中触发,则用户数据指针将变得悬空。
在调用 solClient_context_stopTimer
和上下文线程进入现在死掉的定时器的回调函数之间是否存在竞争?
可能有效或无效的可能解决方案
如果是这样,谁能提出避免尝试访问悬挂指针的方法?我可以想到起点,但他们都有自己的陷阱:
- 不是传递原始指针作为用户数据,而是传递某种 ID,基本上是弱引用,我可以在哈希表中查找它。不幸的是,这意味着哈希表必须是一个全局变量(我希望避免这种情况),因为只有一个用户数据指针,我无法将哈希表对象的地址传递给回调函数。
- 改为使用消息传递取消计时器以避免跨线程对象所有权问题。这意味着我必须将代码覆盖到 运行 上下文线程,以添加队列处理,这对于我的需要来说似乎太复杂了。
- 为对象状态使用某种垃圾收集队列,以便用户数据指针永远不会悬空,而无需来自上下文线程的明确确认。同样,似乎涉及更多的复杂性,因为这本质上涉及为这些计时器 objects/states.
专门分配内存
- 让两个线程在使用计时器时互相排斥。尽管如此,首先要避免在我的回调例程中接收到悬空指针,必须在 进入计时器回调之前 进行锁定,这意味着修改上下文线程的事件循环,例如(2).
此外,我看到定时器 ID 没有传递给定时器例程,因此它无法自行检查它是否在那种不正常的条件下执行。
如果 solClient_context_stopTimer
阻塞当前线程直到任何正在进行的回调例程完成,那么仅在进行该调用后删除状态对象将很容易。但是 API 文档中并不清楚 solClient_context_stopTimer
是否有这样的行为。
是的,C
没有智能指针。 Solace C
API 通过等待上下文线程完成计时器回调来处理这种情况,并且 return SOLCLIENT_FAIL
等待重试时间太长。
简而言之,竞争条件已得到处理,您不需要复杂的解决方法。
情况
我正在使用 Solace C API。
我想关联一个状态对象(在我的例子中是一个 C++ 对象,但对于 C API 它只是 void*
用户数据)当定时器触发并且 Solace 调用我的定时器回调例程时.我用 Solace API 调用 solClient_context_startTimer
.
假设我还想从另一个线程取消定时器,知道 solClient_context_startTimer
返回的定时器 ID。我的问题是我还想取消分配状态对象。因此,如果计时器可以从上下文线程中触发,则用户数据指针将变得悬空。
在调用 solClient_context_stopTimer
和上下文线程进入现在死掉的定时器的回调函数之间是否存在竞争?
可能有效或无效的可能解决方案
如果是这样,谁能提出避免尝试访问悬挂指针的方法?我可以想到起点,但他们都有自己的陷阱:
- 不是传递原始指针作为用户数据,而是传递某种 ID,基本上是弱引用,我可以在哈希表中查找它。不幸的是,这意味着哈希表必须是一个全局变量(我希望避免这种情况),因为只有一个用户数据指针,我无法将哈希表对象的地址传递给回调函数。
- 改为使用消息传递取消计时器以避免跨线程对象所有权问题。这意味着我必须将代码覆盖到 运行 上下文线程,以添加队列处理,这对于我的需要来说似乎太复杂了。
- 为对象状态使用某种垃圾收集队列,以便用户数据指针永远不会悬空,而无需来自上下文线程的明确确认。同样,似乎涉及更多的复杂性,因为这本质上涉及为这些计时器 objects/states. 专门分配内存
- 让两个线程在使用计时器时互相排斥。尽管如此,首先要避免在我的回调例程中接收到悬空指针,必须在 进入计时器回调之前 进行锁定,这意味着修改上下文线程的事件循环,例如(2).
此外,我看到定时器 ID 没有传递给定时器例程,因此它无法自行检查它是否在那种不正常的条件下执行。
如果 solClient_context_stopTimer
阻塞当前线程直到任何正在进行的回调例程完成,那么仅在进行该调用后删除状态对象将很容易。但是 API 文档中并不清楚 solClient_context_stopTimer
是否有这样的行为。
是的,C
没有智能指针。 Solace C
API 通过等待上下文线程完成计时器回调来处理这种情况,并且 return SOLCLIENT_FAIL
等待重试时间太长。
简而言之,竞争条件已得到处理,您不需要复杂的解决方法。