ami*_*.tu 4 c++ multithreading
考虑以下代码,线程是否可能以不同的方式看到对象的状态,尽管它们都是由相同的指针引用的?
using namespace std;
class ProducerAndConsumer{
class DummyObject {
public:
DummyObject() {
sprintf(a, "%d", rand());
}
private:
char a[1000];
};
mutex queue_mutex_;
queue<DummyObject *> queue_;
thread *t1, *t2;
void Produce() {
while (true) {
Sleep(1);
// constructing object without any explicit synchronization
DummyObject *dummy = new DummyObject();
{
lock_guard<mutex> guard(queue_mutex_);
if (queue_.size() > 1000) {
delete dummy;
continue;
}
queue_.push(dummy);
}
}
}
void Consume() {
while (true) {
Sleep(1);
DummyObject *dummy;
{
lock_guard<mutex> guard(queue_mutex_);
if (queue_.empty())
continue;
dummy = queue_.front();
queue_.pop();
}
// Do we have dummy object's visibility issues here?
delete dummy;
}
}
public:
ProducerAndConsumer() {
t1 = new thread(bind(&ProducerAndConsumer::Consume, this));
t2 = new thread(bind(&ProducerAndConsumer::Produce, this));
}
};
Run Code Online (Sandbox Code Playgroud)
你能说这个例子是线程安全的吗?互斥是否强制执行缓存废弃?互斥是否提供了比内存屏障和原子更多的功能?
考虑以下代码,线程是否可能以不同的方式看到对象的状态,尽管它们都是由相同的指针引用的?
答:没有.
说明:获取互斥锁是获取操作,释放它是一个释放操作.
当dummy推入队列时,必须在推动之前进行构造,以便从推动螺纹的角度保持正确的顺序.随后发布的互斥锁将确保发出一个fence,以使其他线程可以看到队列的内容(以及您在此之前修改的所有其他数据).
类似地,在使用者线程中,从该线程的角度来看,将从队列中对dummy的赋值顺序进行正确排序.获取互斥锁将确保内存中的内存DummyObject有效.
支持§1.10.7的引用:
不具有相关联的存储器位置中的同步操作是围栏的,可以是一个获取栅栏,释放栅栏,或两者的获取和释放围栏.
...
例如,获取互斥锁的呼叫将对包含互斥锁的位置执行获取操作.相应地,释放相同互斥锁的调用将在这些相同位置执行释放操作.