处理影响跨不同线程共享对象的定时回调的最佳方法是什么?

What is the best way to handle timed callbacks that affect an object shared across different threads?

本文关键字:回调 定时 最佳 方法 是什么 对象 影响 共享 线程 处理      更新时间:2023-10-16

我有一个类,我们称之为Foo foo,它包含对多个线程有用的数据。这些线程可以调用读写操作(例如 foo->emplace(something((,我由 Foo 内部的互斥锁保护这些操作,并在操作中添加了互斥锁。这是我在实施方面不确定的地方。我必须向foo添加另一条共享信息,我必须调用foo->emplace2(somethingElse(,这将在std::set中存储一些东西,但这应该只存储一分钟。

正确的方法是什么?每当调用 emplace2 并在该线程 emplace 内部休眠 60 秒,然后擦除时,我是否都会从 foo 内部创建一个新线程?我觉得有一种比每次调用 emplace2 时创建大量线程更好的方法。

不是寻找代码,只是一般的实现建议。

您有几个选择:

每个请求一个线程

又名您的解决方案

优势:

  • 易于实施
  • 精确的移除时间

弊:

  • 创建了很多线程。但话又说回来,所有的线程都睡了一辈子,所以这可能不是一个值得解决的问题。

一个队列和一个线程定期检查过期的请求

创建一个队列,用于存储所有请求及其过期时间。有一个线程定期唤醒并删除所有过期的线程

优势:

  • 易于实施
  • 只有一个线程

弊:

  • 必须做出妥协:
    • 增加唤醒和检查频率:这增加了删除请求的精确时间,但也增加了无用唤醒的次数
    • 降低唤醒和检查频率:这降低了删除请求的精确时间,但减少了无用唤醒的次数

一个线程具有精确的唤醒

创建一个包含所有请求及其过期时间的队列。有一个线程仅在下一个请求过期时唤醒。

添加请求时:发出信号并唤醒线程,重新计算下一个过期时间并休眠,直到该时间。

唤醒时:删除即将过期的请求,计算到下一个过期的时间,并在该请求之前休眠。

优势:

  • 最佳性能
  • 精确的移除时间

缺点:

  • 难以实施

什么是最好的方法...

与往常一样,答案是:"视情况而定"。我给了你一些选项,并对每个选项进行了简要分析。由您决定实施哪个,该决定是在性能要求与实施和维护成本之间取得平衡。