【问题标题】:C++ Concurrent modification and read of a single global variableC++ 并发修改和读取单个全局变量
【发布时间】:2015-09-28 09:00:14
【问题描述】:

我在一个类中有一个公共变量

bool toSwitch = false;

Func_Thread1()
{
   if(toSwitch)
   {
      .....
      ....
      toSwitch = false;
   }
}

Func_Thread2()
{
   toSwitch = true;
}

Func_Thread1 将被频繁调用(2 秒一次),在一定的时间间隔内Func_Thread2 将被调用(1 分钟一次)并将全局变量更改为 true。所以在下一次Func_Thread1 调用中,if 条件将变为真。

toSwitch 是否需要同步,因为它可以由不同的线程同时读取和修改..?

更新 2:

在这种环境下会发生什么...?

 Func_Thread1()
    {
       if(toSwitch)
       {
          .....
          ....
       }
       else
       {
         ...
       }
    }

Func_Thread2()
{
   if(toSwitch)
   {
    toSwitch = false;
   }
   else
   {
     toSwitch = true;
   }
}

这里是否需要同步,一个线程修改,另一个线程读取该全局变量的值。?

【问题讨论】:

    标签: c++ multithreading synchronization thread-safety


    【解决方案1】:

    如果一个对象被多个线程访问,并且至少有一个线程是数据竞争的写入器。

    您需要同步的原因如下:

    1. 让编译器不重新排序您对共享变量的访问权限的读写操作。
    2. 让其他线程以一致(原子)和及时(将存储缓冲区刷新到缓存)的方式查看对此变量的更新。

    您的硬件可能能够以原子方式存储bool,但是,出于上述其余原因,您可能希望使用std::atomic<bool>

    【讨论】:

    • 同步实际上并不影响可见性传播的及时性。事实上,这个概念根本不是标准化的(只有一个恳求的说明,要求实现如果他们不介意请传播更新)。同步只影响相对的ordering
    • 我不希望其他线程以原子方式看到更新..让它在下一次调用时看到..如果有任何问题吗?
    • @KerrekSB 你错了。阅读mechanical-sympathy.blogspot.co.uk/2013/02/…了解更多详情。
    • @RahulJain,你必须在这里使用 atomic。 (或其他形式的同步)。没有它,编译器可能会简单地看到 toSwich 在执行线程中从未被修改,并完全放弃您的 if 语句。您可能会逃脱简单的 volatile,但这是非常不明智的。原子写入与互斥锁/写入/互斥解锁可能会在无争议的互斥体上产生相同的速度,但在有争议的互斥体中,原子写入会更快,
    • 问题是不使用同步会导致未定义的行为。它可能会为您可靠地“工作”。它可能会。但它可能会在编译器或操作系统更新之前工作。如果可能会工作到下周二,然后决定转而使用磁盘格式化功能。它可能不会..但是语言中没有任何东西说它会起作用。有一种简单的方法可以告诉编译器你在做什么,这样它就可以总是做正确的事情,那就是使用同步。这就是它的用途!
    【解决方案2】:

    您需要同步。从多个线程对共享内存位置 (toSwitch) 的非同步访问,其中至少一次访问是写入 (toSwitch = true;) 构成数据竞争,这会导致程序的行为未定义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-24
      • 2018-07-14
      • 1970-01-01
      • 2013-01-18
      • 1970-01-01
      • 2013-10-21
      相关资源
      最近更新 更多