Let's consider this piece of code (does not necssarily make sense, it's just a 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 );
}
}
A workerThread
do operations on the Foo
instance. A messupThread
modifies the instance on which operations should be done.
This code is thread safe.
Problem comes if you start 10 workerThread
, when one workerThread
uses the instance, it will lock the other nine one (while doSomething
is thread safe, they should be able to work concurrently).
Is there a kind of weak mutex/lock mechanism that would make any workerThread
prevent messupThread
from changing the instance but would not prevent a concurrent workerThread
to use it.
I could do this, but I'm wondering if there is an easier way to implement that using standard objects/mechanisms:
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 );
}
}
Aucun commentaire:
Enregistrer un commentaire