【发布时间】:2016-02-01 10:31:32
【问题描述】:
考虑到以下代码,线程是否有可能看到对象的状态不同,尽管它们都通过相同的指针引用?
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));
}
};
你能说这个例子是线程安全的吗?互斥锁是否强制缓存垃圾?互斥体是否提供了比内存屏障和原子更多的功能?
【问题讨论】:
-
与问题无关,但如果队列饱和(包含 1001 个对象),您将泄漏虚拟对象。现代 C++ 中推荐的方法是
std::unique_ptr<>,但在continue之前使用简单的delete即可。 -
@dan-allen,我的错,谢谢你注意到这一点)
标签: c++ multithreading