繁体   English   中英

当指向对象的指针作为参数传递给 std::thread 时的内存可见性

[英]Memory visibility when a pointer to an object is passed to std::thread as argument

假设有一个简单的Counter类,它包含一个整数成员count 构造一个新的Counter对象并将count初始化为某个数字。

现在,如果我将指向此对象的指针作为参数传递给新线程,新线程是否会始终立即看到在主线程中初始化的值? 如果是这样,一个不同的线程如何能够在没有任何显式同步的情况下看到主线程所做的更新?

class Counter {
public:
 int count = 0;
} 

void print(Counter* counter) {
  std::cout << counter.count;
}

int main() {
  Counter* cPtr = new Counter();
  cPtr->count = 10;

  pThread = new std::thread(print, cPtr);

  // Assume that the program does not quit until the above
  // thread has finished.
  pThread->join();
}

另一个来自folly文档的folly

EventBase base;
auto thread = std::thread([&](){
  base.loopForever();
});

base正在不同的线程中使用。 如何确保该线程正确地看到base对象的所有初始化字段?

如果这个问题听起来太基本,但我无法找到答案,我深表歉意。

同步并不意味着参数的“更新”。 如果您有一个在线程之间共享的变量,并且该变量被设置为一个线程的值,则所有其他线程将看到相同的值。

同步是关于知道期待值的变化。 例如,如果您有一个设置变量的线程,则其他线程不得尝试同时设置它,否则这将导致变量实际值的 UD。

但是,由于所有线程共享相同的内存,因此不需要“更新”该值。

变量V.线程A组V至1,线程B由A为集读取V,则其值为1。问题是线程B应该读变量(即,是A已经设置之后) -这是同步点。

不需要使int count;的机制int count; 对其他线程可见,因为它只驻留在内存上,指针表示资源的地址,因此任何拥有指向int count的指针的人都可以看到其中驻留的内容(可能有一些特殊情况)。 所以它是自然的,而且是免费的。

同步是一个不同的主题,它不会立即看到更新。 通常用于同步访问/更新资源以防止创建竞争条件等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM