Is the following code MT-Safe?
From: Ken Durden (creepiecrawlies_at_hotmail.com)
Date: 06/30/04
- Next message: Joseph M. Newcomer: "Re: Sharing a socket between threads?"
- Previous message: Jorge: "Sandard dll"
- Next in thread: Joseph M. Newcomer: "Re: Is the following code MT-Safe?"
- Reply: Joseph M. Newcomer: "Re: Is the following code MT-Safe?"
- Reply: Doug Harrison [MVP]: "Re: Is the following code MT-Safe?"
- Messages sorted by: [ date ] [ thread ]
Date: 30 Jun 2004 10:06:40 -0700
Explanation follows code example, MFC synchronization objects used
because thats what I know how to use. Some psuedo-code may be present
where coding in all the parameters wasn't meaningful.
class A
{
public:
A() :
_bRunning(false),
_stopEvent(FALSE,FALSE),
_stoppedEvent(FALSE,FALSE)
{}
void start()
{
CSingleLock( &crit, TRUE );
AfxBeginThread(ThreadFunc, (LPVOID) this, ... );
}
void stop()
{
CSingleLock( &crit, TRUE );
_stoppedEvent.Reset();
_stopEvent.Set();
::WaitForSingleObject( _stoppedEvent, INFINITE );
}
void test()
{
CSingleLock( &crit, TRUE );
if( _bRunning )
stop();
assert( !_bRunning );
}
private:
static UINT ThreadFunc( LPVOID pParam )
{
A * a = (A*) pParam;
a->_bRunning = true;
::WaitForSingleObject( a->_stopEvent, INFINITE );
a->_bRunning = false;
a->_stoppedEvent.Set();
}
CCriticalSection crit;
CEvent _stopEvent;
CEvent _stoppedEvent;
bool _bRunning;
};
int main()
{
A a;
a.start();
a.test();
}
In this simplistic example, assume the only two threads you see are
the only two which are relevant. In this simple example, am I
guaranteed that the assert in the test function will not fire?
I'm worried that the main thread will read the value of _bRunning in
the test() function, and then when it comes time to do the assert,
simply re-use the existing value it has already read, rather than
going back to main memory to get the new value which was set by the
other thread. Is this a valid concern?
Does _bRunning need to be tagged as volatile?
My understanding from school and reading is that it does, but that
supposition blows so many holes in the way most MT programs I've seen
are written its scary. For example, here's another example.. even
simpler:
class B
{
public:
B() : m_pList(NULL) {}
void add( int n )
{
CSingleLock( &crit, TRUE );
if( m_pList == NULL )
m_pList = new std::list<int>();
m_pList->push_back( n );
}
int size()
{
CSingleLock( &crit, TRUE );
if( m_pList == NULL )
return 0;
return m_pList->size();
}
private:
CCriticalSection crit;
std::list<int> * m_pList;
};
In this example, does m_pList need to be declared as
std::list<int> * volatile m_pList
Suppose I have a dozen threads all competing to add items to this
list, without volatile, is there a possibility that one thread will
have a "cached" value of m_pList which is out of date? If the threads
only called add(), it seems that there is no way for the NULL value of
m_pList to be cached in a register; what if the threads also called
size() prior to calling add, however, would this introduce a
possibility for the pointer value to be stored in a register?
Given the relatively small set of registers on Intel processors, how
big an issue is volatile on that platform? What effect does locality
of referencing have? If I reference the same variable 30 C lines apart
from each other does that make a difference from accessing it 2 lines
apart? Do non-inlined function-calls change this behavior?
What are the general guidelines for using volatile? Even if I've got
my locks and events all lined up perfectly, it seems I can still get
burnt without it. I've got a beefed up scenario which models class A
(the first one), I'm going to add volatile to see if I can change the
behavior, but its (dread) low-frequency intermittent problem, so I
won't know for a month if it helped probably.
Thanks alot,
-Ken
- Next message: Joseph M. Newcomer: "Re: Sharing a socket between threads?"
- Previous message: Jorge: "Sandard dll"
- Next in thread: Joseph M. Newcomer: "Re: Is the following code MT-Safe?"
- Reply: Joseph M. Newcomer: "Re: Is the following code MT-Safe?"
- Reply: Doug Harrison [MVP]: "Re: Is the following code MT-Safe?"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|