Quell
September 9th, 2007, 10:40 PM
Hey.
I was wondering how i can lock access to information that is shared by several threads, so that only one call to a function can access the info at once. Ie. We have a function with a static variable. The function is accessed by multiple threads, thus modified the static info, but i don;t want two threads working on the same static variable at the same time. How can i lock the access and wait until it is allowed again?
Thx in advance.
JVene
September 9th, 2007, 11:55 PM
Look into critical sections (CRITICAL_SECTION in MSDN), or perhaps CCriticalSection in MFC.
When a thread locks the critical section, all other threads that attempt such a lock are held until the lock is released, then one at a time, in turn, any pending threads attempting to obtain the lock are scheduled.
There's also the mutex, which can do something so similar as to be identical, but it's a little slower in Windows (critical sections aren't available under Linux, the last I checked for them).
Take some effort to keep the duration of the lock as short as possible (that is, do little else other than act upon the protected variable or resource).
Make certain that all write access to the resource is locked. The critical section is not bound to the variable, which means any code that doesn't honor the critical section can violate the principle of locking. Some developers ensure this with access functions (the typical get/set functions), while others may create locked variable types (template objects that lock against their own critical section before any access to the data they represent).
It's up to you if 'unlocked' access to reading the value is important. Sometimes it's not, but the circumstance isn't all that common. This implies that in most cases all access, read or write, should be under lock for candidate data. This is especially true of certain kinds of containers (linked lists and trees) where the structure of the container might be temporarily invalid from the viewpoint of one thread while being manipulated by another. Even though multiple reads of a linked list wouldn't generally pose a problem, the potential that a write might re-structure the nodes of the list at any time means that any read access could be corrupted unless it is certain that no reads can possible occur while writes are performed (an exceedingly rare situation to guarantee by any means other than locking/unlocking for all access).
MFC's CCriticalSection class simplifies the creation of a critical section object, and the calls required to lock and unlock the section, but the design misses an important RAII concept. It's advisable to create a locking object and use it instead of calling lock and unlock yourself (in C like code, this is referred to as entering and leaving the critical section). Such an object is a very simple, all inline class representing a lock on the critical section. It's constructor accepts a reference or pointer to the critical section object and calls the lock function (enter the critical section). The destructor calls the unlock (leave the critical section), and therefore makes certain, even in the presence of exceptions, that all locks are released.
Quell
September 11th, 2007, 07:57 PM
thx