Software & Finance





Visual C++ - Multithreading Synchronization - Critical Section





Multithreading are very interesting part of programming languages. Visual C++ offers many ways to support  multithreading. You can create thread easily using _beginthread function.

 

Critical Sections are Used to synchronize objects between multiple threads. In this example shows each thread must wait until the earlier thread finishes its task. Critical Sections are used in synchronizing multiple threads in single process.

 


Source Code


#include <afx.h>

#include <afxwin.h>

#include <afxext.h>

#include <atlbase.h>

#include <atlstr.h>

#include <iostream>

#include <vector>

#include <process.h>

 

 

class CMyCriticalSection

{

public:

      CMyCriticalSection() { InitializeCriticalSection(&m_CriticalSection); }

      ~CMyCriticalSection() { DeleteCriticalSection(&m_CriticalSection); }

    void Enter() { EnterCriticalSection(&m_CriticalSection); }

    void Leave() { LeaveCriticalSection(&m_CriticalSection); }

 

 

private:

    CRITICAL_SECTION m_CriticalSection;

};

 

CMyCriticalSection ccs;

 

class CMyLock

{

    CMyCriticalSection *m_pCS;

public:

    CMyLock(CMyCriticalSection *p)

    {

        m_pCS = p;

        //Lock();

    }

 

    ~CMyLock()

    {

        m_pCS->Leave();

    }

 

    void Lock() { m_pCS->Enter(); }

    void Unlock() { m_pCS->Leave(); }

 

};

 

CMyLock lock(&ccs);

void PrintValue(const char *value)

{

    std::cout << value << "\n";

    ::Sleep(200);

}

 

static void f1(void *p)

{

    const char *str = reinterpret_cast<const char*>(p);     

    lock.Lock();

    for(int i = 0; i < 10; i++)

    {

        PrintValue(str);

    }

    lock.Unlock(); 

}

std::vector<HANDLE> hlist;

 

CWinApp theApp;

 

using namespace std;

 

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])

{

       int nRetCode = 0;

 

       // initialize MFC and print and error on failure

       if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))

       {

              // TODO: change error code to suit your needs

              _tprintf(_T("Fatal Error: MFC initialization failed\n"));

              nRetCode = 1;

       }

       else

       {

           HANDLE h1 = (HANDLE) ::_beginthread(f1, 0, "AAA");

        HANDLE h2 = (HANDLE) ::_beginthread(f1, 0, "BBB");

        HANDLE h3 = (HANDLE) ::_beginthread(f1, 0, "CCC");

        hlist.push_back(h1);

        hlist.push_back(h2);

        hlist.push_back(h3);

        WaitForSingleObject(h1, INFINITE);

        WaitForSingleObject(h2, INFINITE);

        WaitForSingleObject(h3, INFINITE);

       }

       return nRetCode;

}

 

Click here to download the VS2005 project and executable

 

 

Output


 

AAA

AAA

AAA

AAA

AAA

AAA

AAA

AAA

AAA

AAA

BBB

BBB

BBB

BBB

BBB

BBB

BBB

BBB

BBB

BBB

CCC

CCC

CCC

CCC

CCC

CCC

CCC

CCC

CCC

CCC