Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. EnterCriticalSection() exception issue

EnterCriticalSection() exception issue

Scheduled Pinned Locked Moved C / C++ / MFC
questionhelp
10 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    Tnarol
    wrote on last edited by
    #1

    Hi, I have a multithreaded program in which I use the following class object "ClassLock" the synchronize accesses : #ifndef CLASSLOCK_H #define CLASSLOCK_H extern CRITICAL_SECTION g_ClassLock; class ClassLock { public: static void InitCriticalSection(); static void DelCriticalSection(); inline ClassLock() { EnterCriticalSection( &g_ClassLock ); } inline ~ClassLock() { LeaveCriticalSection( &g_ClassLock ); } }; #endif I protect a function call by instantiating a ClassLock object at the beginning of the function : void MyFunc() { ClassLock l; ... } But sometimes, don't know why, an exception is thrown. How can I deal with this ? My idea would be the following modification, but I don't know if it's safe and smart : inline ClassLock() { while(!TryEnterCriticalSection( &g_ClassLock )) { } } Any other ideas ? Thanks

    L M B 3 Replies Last reply
    0
    • T Tnarol

      Hi, I have a multithreaded program in which I use the following class object "ClassLock" the synchronize accesses : #ifndef CLASSLOCK_H #define CLASSLOCK_H extern CRITICAL_SECTION g_ClassLock; class ClassLock { public: static void InitCriticalSection(); static void DelCriticalSection(); inline ClassLock() { EnterCriticalSection( &g_ClassLock ); } inline ~ClassLock() { LeaveCriticalSection( &g_ClassLock ); } }; #endif I protect a function call by instantiating a ClassLock object at the beginning of the function : void MyFunc() { ClassLock l; ... } But sometimes, don't know why, an exception is thrown. How can I deal with this ? My idea would be the following modification, but I don't know if it's safe and smart : inline ClassLock() { while(!TryEnterCriticalSection( &g_ClassLock )) { } } Any other ideas ? Thanks

      L Offline
      L Offline
      led mike
      wrote on last edited by
      #2

      Tnarol wrote:

      How can I deal with this ?

      Find out what the exception is. Is the purpose and use model of that class supposed to be evident? I don't get it.

      led mike

      T 1 Reply Last reply
      0
      • L led mike

        Tnarol wrote:

        How can I deal with this ?

        Find out what the exception is. Is the purpose and use model of that class supposed to be evident? I don't get it.

        led mike

        T Offline
        T Offline
        Tnarol
        wrote on last edited by
        #3

        led mike wrote:

        Is the purpose and use model of that class supposed to be evident? I don't get it.

        Yes, First at the beginning of your app you call InitCriticalSection() which is in fact InitializeCriticalSection() on a global g_ClassLock variable Then inside a function when you instantiate a ClassLock object it calls the constructor which locks the g_ClassLock variable using EnterCriticalSection( &g_ClassLock ) When the function return, the ClassLock object goes out of scope, so the destructor is called automatically and it does LeaveCriticalSection( &g_ClassLock ) Therefore the function has the g_ClassLock synchronization token for the duration of its' execution. Then at the end of the program DelCriticalSection must be called...and it does DeleteCriticalSection( &g_ClassLock ).

        L 1 Reply Last reply
        0
        • T Tnarol

          led mike wrote:

          Is the purpose and use model of that class supposed to be evident? I don't get it.

          Yes, First at the beginning of your app you call InitCriticalSection() which is in fact InitializeCriticalSection() on a global g_ClassLock variable Then inside a function when you instantiate a ClassLock object it calls the constructor which locks the g_ClassLock variable using EnterCriticalSection( &g_ClassLock ) When the function return, the ClassLock object goes out of scope, so the destructor is called automatically and it does LeaveCriticalSection( &g_ClassLock ) Therefore the function has the g_ClassLock synchronization token for the duration of its' execution. Then at the end of the program DelCriticalSection must be called...and it does DeleteCriticalSection( &g_ClassLock ).

          L Offline
          L Offline
          led mike
          wrote on last edited by
          #4

          Tnarol wrote:

          on a global g_ClassLock variable

          I don't understand what problem a "global" critical section solves, you want to synchronize everything in the process? :confused:

          led mike

          T 1 Reply Last reply
          0
          • L led mike

            Tnarol wrote:

            on a global g_ClassLock variable

            I don't understand what problem a "global" critical section solves, you want to synchronize everything in the process? :confused:

            led mike

            T Offline
            T Offline
            Tnarol
            wrote on last edited by
            #5

            It's just that a global variable is a simple kind of synchronization resource that can be seen and shared by several threads in a program. I could have this variable static in the class, but there are some strange things happening with static variables members of a class, if you use them very early in the program they are sometimes not yet created and it makes you crash. I don't have a logical explanation for this but that's my experience.

            L 1 Reply Last reply
            0
            • T Tnarol

              It's just that a global variable is a simple kind of synchronization resource that can be seen and shared by several threads in a program. I could have this variable static in the class, but there are some strange things happening with static variables members of a class, if you use them very early in the program they are sometimes not yet created and it makes you crash. I don't have a logical explanation for this but that's my experience.

              L Offline
              L Offline
              led mike
              wrote on last edited by
              #6

              Tnarol wrote:

              It's just that a global variable is a simple kind of synchronization resource that can be seen and shared by several threads in a program.

              I'm sorry but that does not explain anything. A Critical Section is used to synchronize access to data or a section of code, this implies "context" associated with the CS. Have one as "global" elimintates all context.

              Tnarol wrote:

              they are sometimes not yet created

              "Created"? static variable addresses are known at load time, therefore any code that uses them has a good address. Anyway, global or static, I still don't see how that solves anything in regards to using a CS.

              led mike

              1 Reply Last reply
              0
              • T Tnarol

                Hi, I have a multithreaded program in which I use the following class object "ClassLock" the synchronize accesses : #ifndef CLASSLOCK_H #define CLASSLOCK_H extern CRITICAL_SECTION g_ClassLock; class ClassLock { public: static void InitCriticalSection(); static void DelCriticalSection(); inline ClassLock() { EnterCriticalSection( &g_ClassLock ); } inline ~ClassLock() { LeaveCriticalSection( &g_ClassLock ); } }; #endif I protect a function call by instantiating a ClassLock object at the beginning of the function : void MyFunc() { ClassLock l; ... } But sometimes, don't know why, an exception is thrown. How can I deal with this ? My idea would be the following modification, but I don't know if it's safe and smart : inline ClassLock() { while(!TryEnterCriticalSection( &g_ClassLock )) { } } Any other ideas ? Thanks

                M Offline
                M Offline
                Mark Salsbery
                wrote on last edited by
                #7

                void MyFunc() { ClassLock l; ... } You're probably getting an exception because you are entering a critical section that hasn't been initialized yet. You also don't want to create a new critical section every time you enter the function otherwise it will never block. Try this:

                class CMyCriticalSection
                {
                private:
                CRITICAL_SECTION CritSec;
                protected:
                public:
                CMyCriticalSection() {::InitializeCriticalSection(&CritSec);}
                virtual ~CMyCriticalSection() {::DeleteCriticalSection(&CritSec);}

                	void Enter()  {::EnterCriticalSection(&CritSec);}
                	void Leave()  {::LeaveCriticalSection(&CritSec);}
                

                };

                CMyCriticalSection MyFuncCritSec;

                void MyFunc()
                {
                MyFuncCritSec.Enter();

                ... (do thread protected stuff)
                
                MyFuncCritSec.Leave();
                

                }

                T 1 Reply Last reply
                0
                • M Mark Salsbery

                  void MyFunc() { ClassLock l; ... } You're probably getting an exception because you are entering a critical section that hasn't been initialized yet. You also don't want to create a new critical section every time you enter the function otherwise it will never block. Try this:

                  class CMyCriticalSection
                  {
                  private:
                  CRITICAL_SECTION CritSec;
                  protected:
                  public:
                  CMyCriticalSection() {::InitializeCriticalSection(&CritSec);}
                  virtual ~CMyCriticalSection() {::DeleteCriticalSection(&CritSec);}

                  	void Enter()  {::EnterCriticalSection(&CritSec);}
                  	void Leave()  {::LeaveCriticalSection(&CritSec);}
                  

                  };

                  CMyCriticalSection MyFuncCritSec;

                  void MyFunc()
                  {
                  MyFuncCritSec.Enter();

                  ... (do thread protected stuff)
                  
                  MyFuncCritSec.Leave();
                  

                  }

                  T Offline
                  T Offline
                  Tnarol
                  wrote on last edited by
                  #8

                  Thanks, it works fine so far...but the exception occurs very rarely so time will tell. The problem with this kind of class is that you have to leave critical section explicitly so if you have functions with many return points you must copy the "Leave()" everywhere. Anyway I'm quite confident in this implementation.

                  M 1 Reply Last reply
                  0
                  • T Tnarol

                    Thanks, it works fine so far...but the exception occurs very rarely so time will tell. The problem with this kind of class is that you have to leave critical section explicitly so if you have functions with many return points you must copy the "Leave()" everywhere. Anyway I'm quite confident in this implementation.

                    M Offline
                    M Offline
                    Mark Salsbery
                    wrote on last edited by
                    #9

                    >>The problem with this kind of class is that you have to leave critical section explicitly so if >>you have functions with many return points you must copy the "Leave()" everywhere. Cool. I guess I prefer it that way personally :) I can't recall ever needing to block an entire function. Anyway I suspect the exception is unrelated to the critical section. But if it only rarely happens I guess it's ok? Best of luck, Mark

                    1 Reply Last reply
                    0
                    • T Tnarol

                      Hi, I have a multithreaded program in which I use the following class object "ClassLock" the synchronize accesses : #ifndef CLASSLOCK_H #define CLASSLOCK_H extern CRITICAL_SECTION g_ClassLock; class ClassLock { public: static void InitCriticalSection(); static void DelCriticalSection(); inline ClassLock() { EnterCriticalSection( &g_ClassLock ); } inline ~ClassLock() { LeaveCriticalSection( &g_ClassLock ); } }; #endif I protect a function call by instantiating a ClassLock object at the beginning of the function : void MyFunc() { ClassLock l; ... } But sometimes, don't know why, an exception is thrown. How can I deal with this ? My idea would be the following modification, but I don't know if it's safe and smart : inline ClassLock() { while(!TryEnterCriticalSection( &g_ClassLock )) { } } Any other ideas ? Thanks

                      B Offline
                      B Offline
                      Blake Miller
                      wrote on last edited by
                      #10

                      You need two SEPARATE objects. The first object constructor initializes the critical section, and its destructor deletes the critical section. It has a member function Lock() and Unlock() The second class, its constructor Enters the critical section of first object, by calling its Lock function. The destructor of this class calls the Unlock() of the first class. That way, you don't have to worry about calling Unlock() explicitly from your code. You also don't have to use a 'global' class from your common code, you use instances of the second class. If you don't want to block out the entire scope of a function, then use the local scoping operators around the second class and the code like so { SecondClass MyLocker; ... code } and it will release when closing brace is met. This is also handy when there is an exception, your critical section is not permanently locked and lost by the unwinding of the exception.

                      Any sufficiently gross incompetence is nearly indistinguishable from malice.

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups