Multithreading in C++ - Synchronizing Access to gclist
(Page 9 of 11 )
Many of the functions in GCPtr access gclist, which holds the garbage collection list. Access to gclist must be synchronized to prevent two or more threads from attempting to use it at the same time. The reason for this is easy to understand. If access were not synchronized, then, for example, one thread might be obtaining an iterator to the end of the list at the same time that another thread is adding or deleting an element from the list. In this case, the iterator would be invalid. To prevent such problems, each sequence of code that accesses gclist must be guarded by a mutex. The copy constructor for GCPtr shown here is one example:
// Copy constructor.
GCPtr(const GCPtr &ob) {
if(WaitForSingleObject(hMutex, 10000)==WAIT_TIMEOUT)
throw TimeOutExc();
list<GCInfo<T> >::iterator p;
p = findPtrInfo(ob.addr);
p->refcount++; // increment ref count
addr = ob.addr;
arraySize = ob.arraySize;
if(arraySize > 0) isArray = true;
else isArray = false;
instCount++; // increase instance count for copy
ReleaseMutex(hMutex);
}
Notice that the first thing that the copy constructor does is acquire the mutex. Once acquired, it creates a copy of the object and adjusts the reference count for the memory being pointed to. On its way out, the copy constructor releases the mutex. This same basic method is applied to all functions that access gclist.
Two Other Changes There are two other changes that you must make to the original version of the garbage collector. First, recall that the original version of GCPtr defined a static variable called first that indicated when the first GCPtr was created. This variable is no longer needed because hMutex now performs this function. Thus, remove first from GCPtr. Because it is a static variable, you will also need to remove its definition outside of GCPtr.
In the original, single-threaded version of the garbage collector, if you defined the DISPLAY macro, you could watch the garbage collector in action. Most of that code has been removed in the multithreaded version because multithreading causes the output to be scrambled and unintelligible in most cases. For the multithreaded version, defining DISPLAY simply lets you know when the garbage collector has started and when it has stopped.
Next: The Entire Multithreaded Garbage Collector >>
More C++ Articles
More By McGraw-Hill/Osborne
|
This article is taken from chapter three of The Art of C++, written by Herbert Schildt (McGraw-Hill/Osborne, 2004; ISBN: 0072255129). Check it out at your favorite bookstore. Buy this book now.
|
|