【问题标题】:Synchronizing caches in a multithreaded program on multi-core system在多核系统上的多线程程序中同步缓存
【发布时间】:2016-12-17 23:31:19
【问题描述】:

如何确保不同内核/处理器上的缓存在任何时候都相互同步。例如:

Thread 1:
while(1)  {
a++;
}

Thread 2:
While(1)  {
    if(a%2 == 0)  {
    // do something
    }
}

在线程 2 中,当尝试访问 a 时,a 不会反映最新值。这种使用锁的实现会是一个正确的解决方案吗? :

Thread 1:
while(1)  {
a++;
}

Thread 2:
while(1){
    lock();
    unlock();
    if(a%2 == 0)  {
    // do something.
    }
}

期望的行为是我们希望两个线程尽可能同步。

【问题讨论】:

  • 您有一个常见的误解,即内存可见性问题与内存缓存有关。这不是真的。现代处理器确保它们的缓存在硬件中同步(将“MESI 协议”打入您最喜欢的搜索引擎)。为了正确地改写您的问题,您想知道的是如何确保一个线程执行的值更改对其他线程可预见地可见。例如,在您的代码中,主要问题可能是编译器优化将导致 a++ 根本不是内存操作。

标签: multithreading caching operating-system synchronization


【解决方案1】:

如果你想同步 a++;if(a % 2 == 0) { /* do something */ } 你应该试试这个:

std::mutex mtx;

// Thread 1:
while(1)  {
    mtx.lock();
    a++;
    mtx.unlock();
}

// Thread 2:
while(1){
    mtx.lock();
    if(a%2 == 0)  {
        mtx.unlock();
        // do something.
    }
    mtx.unlock();
}

每次要使用特定资源之前锁定特定互斥体,并在完成后解锁它,确保对该资源的操作是同步的。

【讨论】:

  • 这肯定是一个解决方案,但我想知道除了传统的锁/信号量解决方案之外,是否还有其他方法可以解决这个问题?毕竟,需要锁并不是那么难的问题。如果两个线程都在写入变量,我们肯定需要锁。但是一个线程只是在做一个原子读操作,因此我觉得锁是可以避免的。
猜你喜欢
  • 2023-04-02
  • 2011-09-01
  • 2017-03-11
  • 1970-01-01
  • 1970-01-01
  • 2021-11-02
  • 1970-01-01
  • 2010-12-30
相关资源
最近更新 更多