wxCriticalSection

302 views
Skip to first unread message

Tim Burgess

unread,
Mar 29, 2012, 8:42:16 AM3/29/12
to wx-u...@googlegroups.com

Hi,

 

I’m debugging some threading issues I’m having and realised that I don’t really understand wxCriticalSection, as I can’t see how its scope is defined.  I’ve based my threading on the sample application provided, with a dynamic array of custom threads and I have no problems adding threads to the array and removing threads from it.  Similarly, my threads do what they’re supposed to do when I set them running.

 

However, I’m getting problems when I want to interact with data local to an individual thread.  My algorithm follows the following logic:

 

1 – Invoke the thread’s Pause() method;

 

2 – Close the hardware ports that the thread was using;

 

3 – Perform my property editing;

 

4 – Open the hardware ports again;

 

5 – Invoke the thread’s Resume() method.  

 

My array is declared in my .hpp file, with a wxCriticalSection declared immediately below it but, apart from physical proximity, I don’t understand what binds the section to the array – can anybody elucidate, please?

 

Additionally, I tried introducing a wxLocker into my algorithm immediately after pausing my thread, but then seemed to get deadlocked, which doesn’t happen when I run the sample application – I’m assuming that this is because my critical section is faulty somehow.  I’m a novice at multi-threading, so I’m hoping that I’m missing simple.

 

Best wishes.

 

Tim Burgess

Raised Bar Ltd

Phone:  +44 (0)1827 719822

 

Don't forget to vote for improved access to music and music technology at

 

http://www.raisedbar.net/petition.htm

 

 

Michael Himmelreich

unread,
Mar 30, 2012, 12:30:50 AM3/30/12
to wx-u...@googlegroups.com
Hello,

wxCriticalSection is used to make sure that a property is not written by two threads (or written by one thread and read by an other ) at the same time because this could cause unexpected behavior.
Usually I use it like this:

Let's say you have a class with a property that needs to be accessed by different threads running at the same time. Than I usually create a public setter and getter which lock the same wxCriticalSection using wxCriticalSectionLocker:

class A
{
public :
  int getProperty()
  {
     wxCriticalSectionLocker lock( criticalSection );
     return property;
  }
 
  void setProperty( int _property )
  {
     wxCriticalSectionLocker lock( criticalSection );
     this->property = _property;
  }

protected:
  int property;
  wxCriticalSection criticalSection; 
}

In this way you don't have to pause your threads just to edit you properties (if there is no other reason like your hardware ports).

Also you can give all threads access to the same wxCriticalSection-object and every time in your code you have to access a shared property you lock this criticalSection but make sure to unlock it, so you won't end up having a deadlock.
For example anywhere in your code:

{
  wxCriticalSectionLocker lock( crititcalSection );
  ... access Properties...
}

The parentheses make sure the destructor of wxCriticalSectionLocker is called to unlock the criticalSection;

I hope this helps a bit,

Michael Himmelreich
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.
 
To unsubscribe, send email to wx-users+u...@googlegroups.com
or visit http://groups.google.com/group/wx-users

-- 
##############################
Michael Himmelreich Softwaredesign
Kieserstraße 15
07749 Jena

Tel.: 03641 528608
Mobil: 0175 8167674
Email: mic...@himmelweb.de

Tim Burgess

unread,
Mar 30, 2012, 4:45:21 AM3/30/12
to wx-u...@googlegroups.com

Hi,

 

Many thanks for this.  I understand what the critical section is there to achieve, it’s its scope that I’m confused about.  In your example:

 

protected:
  int property;
  wxCriticalSection criticalSection; 

What tells the critical section that it’s guarding the int – is it just the fact that it follows the int’s declaration?

 

Also, from your comments, it would appear that I should close my ports, apply the lock, perform my changes then open my ports again once the locker has run its destructor.  Is this a fair comment, please?

Eran Ifrah

unread,
Mar 30, 2012, 4:59:25 AM3/30/12
to wx-u...@googlegroups.com
The critical section is not associated with any member variable - it is locking portion of code.

In the example provided in previous email the actual locking is done when using the 'Locker' class:
Here is a somewhat simpler example:

int some_second_variable = 2;
int some_variable = 0;

wxCriticalSection gCS;

void foo() 
{
    { 
        wxCriticalSectionLocker locker(gCS);
        // this area is protected by the gCS the protected section ends when the 'locker' goes out of scope
        some_variable += some_second_variable; // this is thread-safe
    }

    // this area is not protected since the 'locker' is not in scope
    some_variable += some_second_variable; // this is NOT thread-safe
}

Note that all threads must refer to the same  wxCriticalSection object (in the example above, gCS is global, so its no problem)
It help to understand what goes inside the  wxCriticalSectionLocker  class:

on its constructor it does something like:

wxCriticalSectionLocker::wxCriticalSectionLocker( wxCriticalSection &cs) : m_cs(cs) { m_cs.Lock(); }
wxCriticalSectionLocker::~wxCriticalSectionLocker()  { m_cs.Unlock(); } 

So as long as the 'Locker' object is "alive", the  wxCriticalSection  object is locked and any thread attempting to lock it will block until the thread who obtained to lock will release it
This is how you achieve the thread-safety - by letting all threads going through the same locker and only one thread can lock it

HTH
Eran
Eran Ifrah
Author of the cross platform, open source C++ IDE: http://www.codelite.org
YTubePlayer http://www.ytubeplayer.com

Tim Burgess

unread,
Mar 30, 2012, 5:42:48 AM3/30/12
to wx-u...@googlegroups.com

That’s great – many thanks for clearing that up for me.

Reply all
Reply to author
Forward
0 new messages