C ++,两个只是没有锁的编写器线程

时间:2018-02-01 14:24:20

标签: c++ linux multithreading

我有3个帖子。

  • 主题A和主题B只是作家。

  • 线程C是一个公正的读者。

  • 变量是time_t。

我需要验证没有数据损坏。 如果数据来自线程A或来自线程B,那么就可以了。

但是,如果变量的结果是来自线程A的数据,则不是来自线程B,因此它已损坏

正如我想的那样,因为time_t可以在一次装配操作中写入 所以没关系。

是吗?

由于

2 个答案:

答案 0 :(得分:6)

如果您有两个潜在的并发写入(1)到共享位置而没有它们之间的同步,则您有未定义的行为,并且可能发生任何事情。所以这是一个坏主意。

请注意,即使您无法根据您对底层架构的了解来判断执行不良,优化器也可能会妨碍,因为它可以假设UB不会发生。

(1)请注意,即使一个编写器和一个没有同步的读卡器也是完全相同的UB。

答案 1 :(得分:4)

time_t是一种算术类型,基本上可以是整数或浮点数。因此,您可以尝试将原子time_t定义为(如果C ++ 11可用):

using atomic_time_t = std::atomic<time_t>;

只要time_t 可以复制,这是可移植的,这可能是由于算术类型。即使不是无锁,它也能正常工作。 (std::atomic的浮点特化添加了C ++ 2a。)

示例:

using atomic_time_t = std::atomic<time_t>;

int main() {
  std::cout << atomic_time_t{}.is_lock_free() << std::endl;
}

使用-std=c++11编译的GCC 7.2 x86_64打印出1。

如果您需要100%确定可移植性,或者没有C ++ 11,请通过线程库提供的互斥锁保护对time_t变量的访问(包括读取和写入)。