views:

450

answers:

3

I am using c++;

in .h: static CRITICAL_SECTION g_CS;

in .cpp: CRITICAL_SECTION CQCommon::g_CS;

but I want to use

   QGUID temp;
   EnterCriticalSection(&g_CS);
   temp = g_GUID++;
   LeaveCriticalSection(&g_CS);
   return temp;

in one static function. How can I invoke InitializeCriticalSection(PCRITICAL_SECTION pcs);

Can I using the following one:

QGUID func(XXX)
{
    static {
    InitializeCriticalSection(&g_CS);
    }
           QGUID temp;
           EnterCriticalSection(&g_CS);
           temp = g_GUID++;
           LeaveCriticalSection(&g_CS);
           return temp;
}

And How can I invoke DeleteCriticalSection(&g_CS) after app leave? Many Thanks for your answers!

Using MFC, it seems CCriticalSection is a solution.

+1  A: 

In the entry point to your code - the main function, call the init:

int main(...)
{
  InitializeCriticalSection(&g_CS);

  // do some stuff

  DeleteCriticalSection(&g_CS);

  // exit
  return 0;
}
1800 INFORMATION
This is the best way to do it - InitializeCriticalSection is very cheap to call.
Michael
+8  A: 

If you want a different approach you can create an object to manage it:

class CriticalSectionManager
{
  public:
  CriticalSectionManager()
  {
    InitializeCriticalSection(&g_CS);
  }
  ~CriticalSectionManager()
  {
     DeleteCriticalSection(&g_CS);
  }
};

void Func(void)
{
  static CriticalSectionManager man;
  //Do stuff
}

This will now be managed automatically by C++. The critical section will be initialized when the function is first entered, and deleted when the program exits.

Furthermore you can extend this by having the actual PCRITICAL_SECTION variable inside the class, etc.. etc..

Ramon Zarazua
+1 Using language features to express your intentions.
Andres Jaan Tack
This code is broken. The C++ standard says nothing about the thread safety of the initialization of a static variable inside a function and you might wind up initializing man twice if two threads execute Func simultaneously.
Michael
+1  A: 

Well, today the best practice is to use "scoped lock" pattern instead of EnterXXX and LeaveXX -like functions. Take a look at what boos has to offer. Regardless, an RAII approach can help you here:

class MyCriticalSection
{
private: 
    CRITICAL_SECTION m_CS;
public:
    MyCriticalSection()
   {
     ::InitializeCriticalSection(&m_CS);
    }
   ~MyCriticalSection()
   {
     ::DeleteCriticalSection(&m_CS);
   }
   void Lock()
   {
     ::EnterCriticalSection(&m_CS);
   }
   void UnLock()
   {
     ::LeaveCriticalSetion(&m_CS);
   }
}
blinnov.com