Click here to Skip to main content
15,892,005 members
Articles / Desktop Programming / MFC
Article

Using templated mutex variables

Rate me:
Please Sign up or sign in to vote.
3.18/5 (15 votes)
21 May 20031 min read 52.1K   558   7   8
Templated class to transparently use variables associated with mutexes

Sample Image - MutexVars.jpg

Introduction

This article demonstrates the use of mutexes and templates to achieve transparency in source code when dealing with mutexed variables. It's also small hack to minimize code rewriting when you want multi-threaded solutions ported from single-threaded ones.

Next, i'll give you some background about the concepts behind this article and how to use the developed code in your applications.

Background

Let's start with a simple example of a single-threaded application performing some operations:

C++
boolean CanStartStep2 = false;

void compute()
{
    for (int i = 0; i < 500; i++)
    {
        // do some work
        if (i == 50)
            CanStartStep2 = true;
    }

    while (!CanStartStep2)
        ;

    for (int i = 0; i < 100; i++)
    {
        // do some work
    }
}
It's easy to understand that the given example could be split into worker threads, something like the next example (keep in mind that this is a simple example):
C++
boolean CanStartStep2 = false;
CMutex mut;

static UINT Thread1Proc(LPVOID)
{
    mut.Lock();
    CanStartStep2 = false;
    mut.Unlock();

    for (int i = 0; i < 50000; i++)
    {
        // do some work
        if (i == 10)
        {
            mut.Lock();
            CanStartStep2 = true;
            mut.Unlock();
        }
    }

    return 0;
}

static UINT Thread2Proc(LPVOID)
{
    boolean b;

    do {
        mut.Lock();
        b = CanStartStep2;
        mut.Unlock();
    } while (!b);

    for (int i = 0; i < 100; i++)
    {
        // do some work
    }

    return 0;
}
You can see that when you need to access the shared variable you always have to work explicitly with a mutex. This article explains a simple, yet powerfull way to use variables without explicit uses of mutexes. It's pretty useful when dealing with any type of global application state variables, etc..

To achieve this functionallity, i've implemented a small templated class MutexVar<typename T> wrapping up these concepts.
The previous example can be rewritten, cleaning up all the explicit mutex Lock() and Unlock() calls:

C++
MutexVar<boolean> CanStartStep2 = false;

static UINT Thread1Proc(LPVOID)
{
    for (int i = 0; i < 50000; i++)
    {
        // do some work
        if (i == 10)
            CanStartStep2 = true;
    }

    return 0;
}

static UINT Thread2Proc(LPVOID)
{
    while (!CanStartStep2)
        ;

    for (int i = 0; i < 100; i++)
    {
        // do some work
    }

    return 0;
}

Using the code

It's easy to use the code, just follow these steps:

Include the header file:

C++
#include "MutexVar.h"

Declare a variable (e.g. a mutexed int variable):

C++
MutexVar<int> i = 0;

Start using it like any other int, e.g.:

C++
i = 100;
int j = i * 2;

cout << i << endl;

Conclusions

I hope this article can help you develop shorter, more efficient and more reusable code. That's all, folks!

Bugs

  • Some operators don't work (++, --, amongst others);
  • All functions using va_args (printf, etc.) need an explicit cast to read a variable value, or else will use variable memory address (thanks walker_andrew_b);
  • I'm pretty sure there are some more bugs i haven't found...

History

Version 0.1.0: 17/05/2003

  • Initial release

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


Written By
Web Developer
Portugal Portugal
Rui Lopes is doing a Post-Graduation on Digital Talking Books and does some research on Human Computer Interaction and Multimedia at the Faculty of Sciences, University of Lisbon, Portugal.

Comments and Discussions

 
Generalproblem Pin
gaz6623-Sep-04 22:31
gaz6623-Sep-04 22:31 
GeneralSleep Pin
Paul Evans26-May-03 23:58
Paul Evans26-May-03 23:58 
Hi there,
Just noticed you are using loops (some infinite) and never allowing any time back - which on some systems could cause the rest of windows to become unresponsive.

Remember to use Sleep(1); or something similar somewhere in your code. The 1 is the minimum time you allow some time back to the rest of the system - it may take longer then a millisecond to come back but putting this line in at your while... and for... loops when they are supposed to be working would ensure you're playing fair with the processors time Wink | ;)

Thanks,

Paul

/**********************************
Paul Evans, Dorset, UK.
Personal Homepage "EnjoySoftware" @
http://www.enjoysoftware.co.uk/
**********************************/

GeneralRe: Sleep Pin
Rui Dias Lopes27-May-03 16:37
Rui Dias Lopes27-May-03 16:37 
GeneralRe: Sleep Pin
Paul Evans27-May-03 22:18
Paul Evans27-May-03 22:18 
GeneralRe: Sleep Pin
Rui Dias Lopes28-May-03 5:50
Rui Dias Lopes28-May-03 5:50 
GeneralWell done Pin
Paul Evans26-May-03 22:45
Paul Evans26-May-03 22:45 
GeneralRe: Well done Pin
Rui Dias Lopes27-May-03 16:28
Rui Dias Lopes27-May-03 16:28 
GeneralRe: Well done Pin
peterchen20-Oct-04 5:54
peterchen20-Oct-04 5:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.