我有一个循环运行的工作线程,偶尔做一些工作。我想要一个经理线程 keeps a watchful eye on whether the first thread has done any work recently .
我认为最简单的方法是使用一个包含时间戳的变量;当工作线程做一些工作时,它将当前时间写入变量,当管理线程要检查工作线程时,它从变量中读取时间并测量与当前时间的差异。
首先,这个变量需要是原子的吗?我的直觉是在线程间通信时使用原子,但在这种情况下,没有读-修改-写循环,只有一个线程在进行更新。时间值应该足够小以适合单个单词,所以也许也不用担心单词撕裂。以某种方式鼓励线程之间的及时传播是否仍然是原子的?如果不是,共享时间戳的正确方法是什么?
其次,表示时间戳的合适类型是什么,我如何获得它的实例? std::time::Instant 似乎是显而易见的选择,但它不是同步或发送,而且我不知道我怎么会有一个原子的。有更好的选择吗?
最佳答案
到目前为止我所做的是编写我自己的 AtomicInstant。 Instant 的内容是特定于平台且隐藏良好的,但它可以转换为另一个 Instant 的偏移量,以 Duration 的形式,后者又可以转换为纳秒计数。反过来,可以将其填充到 usize 中,只要您测量的时间相对于机器的字长而言不会太大(一天大约是 2**46 纳秒;64位机可测约350年)。该转换链都可以反转以读取值。
代码看起来像这样(稍作编辑,所以这可能是错误的):
struct AtomicInstant {
base: Instant,
offset: AtomicUsize,
}
impl AtomicInstant {
fn new(base: Instant) -> AtomicInstant {
AtomicInstant {
base: base,
offset: AtomicUsize::new(0),
}
}
fn load(&self, order: Ordering) -> Instant {
let offset_nanos = self.offset.load(order) as u64;
let secs = offset_nanos / 1_000_000_000;
let subsec_nanos = (offset_nanos % 1_000_000_000) as u32;
let offset = Duration::new(secs, subsec_nanos);
return self.base + offset;
}
fn store(&self, val: Instant, order: Ordering) {
let offset = val - self.base;
let offset_nanos = offset.as_secs() * 1_000_000_000 + offset.subsec_nanos() as u64;
self.offset.store(offset_nanos as usize, order);
}
}
关于multithreading - 从线程到另一个共享时间戳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42537228/