Personal page of Konjengbam

“Bluetooth adopter, technology enabler and innovative thinking”

Text Box: Safer Queue

Description

STL provides a basic sequence known as deque (a double-ended queue). A deque is a sequence optimized so that operations at both ends are about as efficient as for a list, whereas subscripting approaches the efficiency of a vector. A deque is used where additions and deletions take place "at the ends".

Purpose

If this deque is to be accessed in different threads, some form of synchronization of the queue access would be necessary, for example, providing locking and unlocking mechanism.

In view of this, it seems necessary and good to have a class that can be as flexible as to allow usage in multi-threaded environment as well. A wrapper class for deque - provides the same efficiency but provides extra feature of thread synchronization.

For instance, we could model the following class:

template < class T >
class CSafeQueue
{
public:
      // Constructor(s) and Destructor
      CSafeQueue()
      {
      InitQueue(); // Initializes critical section and creates
      // queue event indicator handle
      }

      virtual ~CSafeQueue()
      {
      if ( GetQueueFlag() != NULL )
      DeleteQueue(); // Deletes contents and critical section
      // before finally closing the event indicator handle.
      }

      // Public operations

      // Adds element to queue
      void AddTail( const T* pElement )
      {
      LockQueue();
      m_queue.push_back( *pElement );
      UnlockQueue();

      // Set modified flag
      SetQueueFlag();
      }
      ...
      ...
private:
      ...
      // Locks the current queue object
      void LockQueue()
      {
      EnterCriticalSection( &m_criticalSection );
      }

      // Unlocks current queue
      void UnlockQueue()
      {
      LeaveCriticalSection( &m_criticalSection );
      }
      ...
      ...
}

Thus, what we have is an efficient queue template class that can store any data type sequence to implement FIFO and yet have the features of thread synchronization.

 

Example Usage:

CSafeQueue< int > intQueue; // queue of integer values

intQueue.AddTail( 1 );
intQueue.AddTail( 2 );
intQueue.AddTail( 3 );

while( !intQueue.IsEmpty() )
{
int *pInt = (int*)intQueue.RemoveFront();
if ( pInt != NULL )
cout << "Removing " << *pInt << endl;
}
// Delete queue
intQueue.DeleteQueue();


In the case of multi-threaded system, before deleting, one could call functions like CanDelete() first before calling DeleteQueue(). CanDelete() checks if the queue handle is being hold by any thread. If no threads hold this, it will have a non-signaled state and the queue handle can also be closed at the time of deleting queue.

Also, in similar fashion, we can write thread-safe wrapper class for vector.

View code here

Hosted by www.Geocities.ws

1