5,666,979 members and growing! (15,478 online)
Email Password   helpLost your password?
General Programming » Threads, Processes & IPC » General     Intermediate

A "synchronized" statement for C++ like in Java

By Achilleas Margaritis

Design and implementation of a "synchronized" C++ statement that works like the one in Java.
C++, Windows, Visual Studio, Dev

Posted: 18 Dec 2005
Updated: 18 Dec 2005
Views: 25,571
Bookmarked: 15 times
Announcements
Loading...



Search    
Advanced Search
Sitemap
20 votes for this Article.
Popularity: 5.06 Rating: 3.89 out of 5
3 votes, 15.0%
1
3 votes, 15.0%
2
2 votes, 10.0%
3
3 votes, 15.0%
4
9 votes, 45.0%
5

Introduction

This article shows how to code a synchronized statement in C++ that works in a similar way to Java. The target of this code is to make a piece of code like the following, compilable and executable in C++:

synchronized(myMutex)
{
    //TODO put synchronized code here

}

The Mutex class

The following piece of code presents a mutex class with lock/unlock semantics (common in many libraries):

//mutex class

class Mutex
{
public:
    //the default constructor

    Mutex()
    {
        InitializeCriticalSection(&m_criticalSection);
    }

    //destructor

    ~Mutex()
    {
        DeleteCriticalSection(&m_criticalSection);
    }

    //lock

    void lock()
    {
        EnterCriticalSection(&m_criticalSection);
    }

    //unlock

    void unlock()
    {
        LeaveCriticalSection(&m_criticalSection);
    }

private:
    CRITICAL_SECTION m_criticalSection;
};

There is nothing particularly special for the above class:

  • it initializes the critical section upon construction,
  • it deletes the critical section,
  • the method lock() locks the critical section, and
  • the method unlock() unlocks the critical section.

We are going to use critical sections, but any synchronization primitive applies.

The Lock class

In order to be consistent with the C++ established code practices, we need a special class for implementing the RAII (Resource Acquisition Is Initialisation) pattern. The following piece of code shows such a class:

//synchronization controller object

class Lock
{
public:
    //the default constructor

    Lock(Mutex &mutex) : m_mutex(mutex), m_locked(true)
    {
        mutex.lock();
    }

    //the destructor

    ~Lock()
    {
        m_mutex.unlock();
    }

    //report the state of locking when used as a boolean

    operator bool () const
    {
        return m_locked;
    }

    //unlock

    void setUnlock()
    {
        m_locked = false;        
    }

private:
    Mutex &m_mutex;
    bool m_locked;
};

Things to note for this class:

  • it locks the mutex upon construction, and
  • it unlocks the mutex upon destruction.

Using the above class is pretty straightforward:

Mutex mutex1;
...
Lock lock1(mutex1);
//synchronized code here

The "synchronized" macro

The synchronized statement can be coded as a macro like this:

#define synchronized(M)  for(Lock M##_lock = M; M##_lock; M##_lock.setUnlock())

where, the parameter M is the mutex variable to use for locking.

Example of using the "synchronized" macro

The following piece of code shows how to use the synchronized macro: it coordinates two threads that print the alphabet in the standard output. Without synchronization, the output is not correct:

//thread count

int thread_count = 0;

//mutex

Mutex mutex1;

//example thread

DWORD CALLBACK thread_proc(LPVOID params)
{
    for(int i = 0; i < 10; ++i)
    {
        synchronized(mutex1)
        {
            for(char c = 'A'; c <= 'Z'; ++c)
            {
                cout << c;
            }
            cout << endl;
        }
    }
    thread_count--;
    return 0;
}

//main

int main()
{
    thread_count = 2;
    CreateThread(0, 0, thread_proc, 0, 0, 0);
    CreateThread(0, 0, thread_proc, 0, 0, 0);
    while (thread_count) Sleep(0);
    getchar();
    return 0;
}

How it works

The macro exploits the nature of the for statement of C++ to do the following (in the presented order):

  1. initialization part: a local lock variable is defined that locks the given mutex; the lock variable contains an internal flag which is set to true.
  2. test part: the lock variable is tested and found to be true: the code inside the loop is executed.
  3. increment part: the lock variable's internal flag is set to false.
  4. test part: the lock variable is tested and found to be false: the loop exits.
  5. exit part: the lock variable is destroyed, unlocking the mutex.

Advantages over classic RAII

Using this way to code RAII has some advantages over the traditional method:

  • it makes the code more readable,
  • it helps avoiding declaration of lock variables, and
  • it ties the code to be synchronized with the synchronization scope.

Notes

The synchronized macro is exception-safe, since it unlocks its mutex upon destruction.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Achilleas Margaritis



Occupation: Web Developer
Location: Greece Greece

Other popular Threads, Processes & IPC articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 13 of 13 (Total in Forum: 13) (Refresh)FirstPrevNext
GeneralHere is my version.memberpedro.alves9:02 20 Dec '05  
GeneralRe: Here is my version.memberpedroalves0:18 26 Dec '05  
GeneralRe: Here is my version.memberpedroalves0:21 26 Dec '05  
GeneralC++ is not Java ... It's bettermember[Deep]Xor22:18 19 Dec '05  
GeneralNeeds ImprovementmemberDavid Patrick1:02 19 Dec '05  
GeneralRe: Needs ImprovementmemberAchilleas Margaritis2:22 19 Dec '05  
GeneralRe: Needs ImprovementmemberRoland Pibinger12:50 19 Dec '05  
GeneralC++ versions ?memberRobert Bielik23:57 18 Dec '05  
GeneralRe: C++ versions ?memberAchilleas Margaritis2:14 19 Dec '05  
GeneralRe: C++ versions ?memberPeter Ritchie6:35 20 Dec '05  
GeneralC++ versions !memberRobert Bielik21:31 20 Dec '05  
GeneralRe: C++ versions !memberpedro.alves8:29 21 Dec '05  
GeneralRe: C++ versions !memberPeter Ritchie9:24 23 Dec '05  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 18 Dec 2005
Editor: Smitha Vijayan
Copyright 2005 by Achilleas Margaritis
Everything else Copyright © CodeProject, 1999-2008
Web13 | Advertise on the Code Project