Re: CRITICAL SECTION Help!
- From: "Ron H." <rnh@xxxxxxx>
- Date: Wed, 7 Feb 2007 10:15:56 -0600
THANKS Joe! As usual you came through with straight forward and
understandable answers!
Regards
Ron H.
"Joseph M. Newcomer" <newcomer@xxxxxxxxxxxx> wrote in message
news:2ipjs2tt3oh079qiplvqjiq937b7t22lnr@xxxxxxxxxx
Actually, you don't need a critical section to update a simple integer. A
simple
assignment will do it, because even in a multiprocessor the assignment is
atomic and this
is managed by the hardware. Note that the value must be DWORD-aligned,
which is usually
typical unless you are doing weird things inside structs/classes.
As long as the intFrequency (why the prefix? It doesn't convey anything
useful) has no
relationship to other variables that must be changed concurrently, then
there is no need
to lock. However, it should be declared volatile, so the compiler knows
to not optimize
the code in some way that prevents the actual execution from seeing the
change.
A CRITICAL_SECTION is required only when there is a set of related changes
greater than a
single scalar value whose integrity must be maintained, and that during
the updating,
there are times in which values are inconsistent with each other. Typical
examples are
unlinking objects from lists, putting objects into queues, making sure the
name and the
address are both consistent, and anything dealing with multibyte values
larger than a
single DWORD being written.
You do not need to make a global declaration; you only need a declaration
that has the
same scope and extent as the value in question. If intFrequency is
global, then the scope
and extent of your CRITICAL_SECTION would be global. If intFrequency is a
class member,
then the CRITICAL_SECTION would be a class member.
Now, if Frequency were a LONGLONG (__int64) it would take two write
operations to update
it. This would now be a disaster. So you would do
LONGLONG Frequency;
CRITICAL_SECTION FrequencyLock;
I would handle this by declaring
class FrequencyInfo {
public:
FrequencyInfo() { InitializeCriticalSection(&lock); }
virtual ~FrequencyInfo() { DeleteCriticalSection(&lock); }
LONGLONG Get() {
EnterCriticalSection(&lock);
LONGLONG result = Frequency;
LeaveCriticalSection(&lock);
return result;
}
void Set(LONGLONG val) {
EnterCriticalSection(&lock);
Frequency = val;
LeaveCriticalSection(&lock);
}
protected:
volatile LONGLONG Frequency;
CRITICAL_SECTION lock;
}
So I would never worry about the variable or the lock or anything else.
This would be the
best method. Scattering CRITICAL_SECTION values and variables around is
not a reasonable
approach in general.
FrequencyInfo frequency;
then just use the accessors
LONGLONG f = frequency.Get();
or
frequency.Set(newvaluehere);
By the way, don't try to make arguments about efficiency; they are
irrelevant. In release
mode, the functions will be quite likely compiled inline anyway, and if
they aren't, it
doesn't matter. The code is clean, and will remain correct even as
changes are made.
But for a simple 32-bit scalar value, the locking is intrinsic in the
hardware. This
works as long as all you do are assignments. If you did +=, -=, etc. then
you would need
to lock. For simple arithemtic, InterlockedExchangeAdd,
InterlockedIncrement and
InterlockedDecrement would do fine (actually, my LONGLONG example is poor
in that there is
an InterlockedExchange64 operator as well that handles this case)
joe
On Wed, 7 Feb 2007 06:23:04 -0600, "Ron H." <rnh@xxxxxxx> wrote:
OK, I have two threads running. One handles an encoder input with aJoseph M. Newcomer [MVP]
hardware
counter/timer and determines a frequency (as intFrequency) over a small
interval ( 1 second ). The other thread needs to use the measured
frequency.
I am confused about how to use a critical section to allow the first
thread
to update the value of intFrequency and be certain that the second thread
can get a valid value for intFrequency everytime it needs it. Where do I
put
the critical section? Do I make it a global declaration and use the
enter/leave members from both threads?
Is there an good on-line tutorial on using the critical section for
accessing a variable from two threads?
Regards
Ron H.
-----------------
www.Newsgroup-Binaries.com - *Completion*Retention*Speed*
Access your favorite newsgroups from home or on the road
-----------------
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
-----------------
www.Newsgroup-Binaries.com - *Completion*Retention*Speed*
Access your favorite newsgroups from home or on the road
-----------------
.
- References:
- CRITICAL SECTION Help!
- From: Ron H.
- Re: CRITICAL SECTION Help!
- From: Joseph M . Newcomer
- CRITICAL SECTION Help!
- Prev by Date: Re: How to export afunction in class?
- Next by Date: Re: Escape key
- Previous by thread: Re: CRITICAL SECTION Help!
- Next by thread: Re: CRITICAL SECTION Help!
- Index(es):