【发布时间】:2017-10-06 09:42:04
【问题描述】:
让我们考虑这段代码(不一定有意义,它只是一个 MCVE):
class Foo
{
public:
// this function is thread safe
void doSomething();
};
static std::mutex mutex;
static std::shared_ptr<Foo> instance;
void workerThread()
{
while ( true )
{
mutex.lock();
if ( instance )
{
instance->doSomething();
}
mutex.unlock();
msleep( 50 );
}
}
void messupThread()
{
while ( true )
{
mutex.lock();
instance.reset( new Foo() );
mutex.unlock();
msleep( 1000 );
}
}
workerThread 对 Foo 实例执行操作。 messupThread 修改应在其上执行操作的实例。
这段代码是线程安全的。
如果你启动 10 个workerThread 就会出现问题,当一个workerThread 使用该实例时,它会锁定另外九个(而doSomething 是线程安全的,它们应该能够同时工作)。
是否有一种弱互斥/锁定机制可以使任何workerThread 阻止messupThread 更改实例但不会阻止并发workerThread 使用它。
我可以这样做,但我想知道是否有更简单的方法来使用标准对象/机制来实现它:
class Foo
{
public:
// this function is thread safe
void doSomething();
};
static int useRefCount = 0;
static std::mutex work_mutex; // to protect useRefCount concurrent access
static std::mutex mutex; // to protect instance concurrent access
static std::shared_ptr<Foo> instance;
void workerThread()
{
while ( true )
{
work_mutex.lock();
if ( useRefCount == 0 )
mutex.lock(); // first one to start working, prevent messupThread() to change instance
// else, another workerThread already locked the mutex
useRefCount++;
work_mutex.unlock();
if ( instance )
{
instance->doSomething();
}
work_mutex.lock();
useRefCount--;
if ( useRefCount == 0 )
mutex.unlock(); // no more workerThread working
//else, keep mutex locked as another workerThread is still working
work_mutex.unlock();
msleep( 50 );
}
}
void messupThread()
{
while ( true )
{
mutex.lock();
instance.reset( new Foo() );
mutex.unlock();
msleep( 1000 );
}
}
【问题讨论】:
-
我认为你想要的是
shared_mutex- 你想要messupThread到lock()/unlock()通常和workerThread到lock_shared()/unlock_shared()。 -
相信你可能在找
std::shared_mutex。 -
这种模式被称为“Single Writer/Multiple Reader”。
标签: c++ multithreading c++11 c++14 mutex