Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ MT-multithreading and servers » Use same variable in different threads
Re: Use same variable in different threads [message #30186 is a reply to message #30181] Tue, 14 December 2010 09:02 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3354
Registered: August 2008
Senior Veteran
Great Didier

The status now is to use AtomicVar and ScopedLock.

Thank you all Smile.



Best regards
Iñaki
Re: Use same variable in different threads [message #30350 is a reply to message #30186] Sat, 25 December 2010 20:45 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
ScopedLock is in U++ as Mutex::Lock.

For read/write access, please notice RWMutex (multiple readers, just one writer). It has 'scoped' RWMutex::ReadLock and RWMutex::WriteLock variants.

As for Atomic variables, its basic feature is that they can accessed and perform increments/decrements from multiple threads WITHOUT caring about mutexes or barriers.

[Updated on: Sat, 25 December 2010 20:49]

Report message to a moderator

Re: Use same variable in different threads [message #30453 is a reply to message #30181] Sun, 02 January 2011 01:12 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3354
Registered: August 2008
Senior Veteran
Hello Didier

Trying to use the code like this I get a "error C2955: 'ScopedLock' : use of class template requires template argument list". What am I doing wrong?

Why ScopedLock has to be templated?

Didier wrote on Mon, 13 December 2010 22:48

Hi Koldo,

I would add just one last thing:
DEADLOCKs ==> what MT programs dread the most.

In practice, there is a case in C++ where deadlocks can appear without notice : when an exception occurs.

Imagine an exception occurs in the middle of you're "slow operation" ==> the mutex doesn't get released ==> a deadlock will come up soon enough Confused

To avoid this I use, what I call a ScopedLock class:

template<class MUTEX>
class ScopedLock
{
private:
	MUTEX& mutex;

private:
	// The following constructor/operators are expilictly FORBIDDEN
        // because they have no meaning
	ScopedLock(void) {};
	ScopedLock(const ScopedLock& ) {};
	ScopedLock& operator=(ScopedLock& ) { return *this; };

public:
	inline 	ScopedLock(MUTEX& mut)
	: mutex(mut)
	{
		mutex.lock();
	}

	inline ~ScopedLock(void)
	{
		mutex.unLock();
	}
};


The point is to create a 'ScopedLock' object when interring a protected zone of code, and when the scope ends ==> the unlock is automatically done IN ALL POSSIBLE CASES !! even exceptions: The compiler handles all for you Cool

so you're code would become:
void ThreadFunction(){
	for(int i = 0; i < 10; i++){
		Thread::Sleep(Random(10)); // Pretend some work...
		{
			ScopedLock(data.m);// Enter the section that accesses the shared data
			data.a = i;
			data.c << data.a << "\n";
			Thread::Sleep(20); //Let's pretend that some slow operation happens here (for example file access)
			data.b = data.a;
		} // implicit release
	}
}


You don't have any more "mutex leaks" possible



Best regards
Iñaki
Re: Use same variable in different threads [message #30454 is a reply to message #30453] Sun, 02 January 2011 03:08 Go to previous messageGo to next message
gprentice is currently offline  gprentice
Messages: 260
Registered: November 2005
Location: New Zealand
Experienced Member
It's time you learnt C++ templates Koldo Smile

ScopedLock is a template class because it's declared like this

template<class MUTEX>
class ScopedLock
{

It has one template parameter named MUTEX. When you use a template class you have to specify template arguments corresponding to all the template parameters
i.e.
#include <Core/Mt.h>
struct mySharedData {
	int a, b;
	String c;
	Mutex m;
};

mySharedData data;

    // ...
    ScopedLock<Mutex> xyz(data.m);

where Mutex (the template argument in between <>) is the U++ mutex class in core/mt.h
You also need to change the call mutex.lock() to mutex.Enter() and mutex.unLock() to mutex.Leave

It's actually pretty much pointless to make the ScopedLock class a template class so you could either change it to a normal class or maybe put a default argument

template<class MUTEX = Mutex>
class ScopedLock
{

then you can do
    // ...
    ScopedLock xyz(data.m);

When xyz goes out of scope, the destructor is called which releases the mutex.

By the way, this code is invalid as you can't call a constructor.
    ScopedLock(data.m);// Enter the section that ...

The Mutex::Lock class that Mirek mentioned, creates a temporary mutex so can't be used in your case if you have other code elsewhere that is accessing the data.

Graeme

[Updated on: Sun, 02 January 2011 03:09]

Report message to a moderator

Re: Use same variable in different threads [message #30456 is a reply to message #30453] Sun, 02 January 2011 12:18 Go to previous messageGo to next message
Didier is currently offline  Didier
Messages: 680
Registered: November 2008
Location: France
Contributor
Hi Koldo,

In fact this helper class is intended to work with all sorts of mutexes: whatever you want as long as the methods 'lock' and 'unlock' exist.

The code is therefore 'portable'... but it can't be used directly in Upp since the methods 'lock' & 'unlock' are called 'Enter' and 'Leave'
The reason why I did this is to make 'POLICY BASED DESIGN' code:
http://en.wikipedia.org/wiki/Policy-based_design
http://loki-lib.sourceforge.net/index.php?n=Main.Policy-base dDesign
http://www.amazon.com/exec/obidos/ASIN/0201704315/modecdesi- 20


In you're case, just use
Mutex::Lock( <you're mutex> )

It should do what you need.

Quote:

The Mutex::Lock class that Mirek mentioned, creates a temporary mutex

This is not true, a reference is used so the behavior is exactly the same as my template.
Re: Use same variable in different threads [message #30458 is a reply to message #30456] Sun, 02 January 2011 13:11 Go to previous messageGo to next message
gprentice is currently offline  gprentice
Messages: 260
Registered: November 2005
Location: New Zealand
Experienced Member
Didier wrote


In you're case, just use
Mutex::Lock( <you're mutex> )

It should do what you need.

Quote:

The Mutex::Lock class that Mirek mentioned, creates a temporary mutex

This is not true, a reference is used so the behavior is exactly the same as my template.


uh, oops, you're so right. The code Koldo needs is then
    Mutex::Lock xyz(data.m);


Re: Use same variable in different threads [message #30459 is a reply to message #30350] Sun, 02 January 2011 15:35 Go to previous messageGo to next message
tojocky is currently offline  tojocky
Messages: 607
Registered: April 2008
Location: UK
Contributor

mirek wrote on Sat, 25 December 2010 21:45

ScopedLock is in U++ as Mutex::Lock.

For read/write access, please notice RWMutex (multiple readers, just one writer). It has 'scoped' RWMutex::ReadLock and RWMutex::WriteLock variants.

As for Atomic variables, its basic feature is that they can accessed and perform increments/decrements from multiple threads WITHOUT caring about mutexes or barriers.



Mirek,

You read my mind. RWMutex seems to be perfect.
Windows variant I see
1. a limitation: only LONG_MAX concurrent reads can be. if concurrent reads > LONG_MAX then result is undefined.
Linux variant is a kernel variant. I didn't found the source code and can't say the opinion.
2. If write in recursive mode by the same phread will wait to infinitely.

The linux version is more pretty realized according by this links source code:
http://www.jbox.dk/sanos/source/include/pthread.h.html
http://www.jbox.dk/sanos/source/lib/pthread/rwlock.c.html



Re: Use same variable in different threads [message #30462 is a reply to message #30459] Sun, 02 January 2011 18:38 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
tojocky wrote on Sun, 02 January 2011 09:35


Windows variant I see
1. a limitation: only LONG_MAX concurrent reads can be. if concurrent reads > LONG_MAX then result is undefined.



Which is not real limitation at all. You are not going to have LONG_MAX threads anyway - you would run out of memory much sooner...
Re: Use same variable in different threads [message #30463 is a reply to message #30462] Sun, 02 January 2011 19:06 Go to previous messageGo to next message
koldo is currently offline  koldo
Messages: 3354
Registered: August 2008
Senior Veteran
Sorry boys

I do not understand............

Just to simplify it:

Data to share:
struct ToProtect {
	...
	Mutex mtx;
};


Code protected by the Mutex. This seem to work:
	mtx.Enter();
	...
	mtx.Leave();


Theoretically ScopedLock saves us the "Leave". However it does not work now.

How ScopedLock should be and how it would have to be used?

This does compiling errors:

ScopedLock<Mutex>(mtx);


Best regards
Iñaki
Re: Use same variable in different threads [message #30465 is a reply to message #30463] Sun, 02 January 2011 22:56 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
koldo wrote on Sun, 02 January 2011 13:06

Sorry boys

I do not understand............

Just to simplify it:

Data to share:
struct ToProtect {
	...
	Mutex mtx;
};


Code protected by the Mutex. This seem to work:
	mtx.Enter();
	...
	mtx.Leave();





Not sure about ScopedLock, but

Mutex::Lock dummyname(mtx);

should work.

Or, if you wish, you can also use

INTERLOCKED_(mtx) {
}

Mirek

P.S.: For 'dummyname', I tend to use '__' to indicate that the name is irrelevant.

Mutex::Lock __(mtx);
Re: Use same variable in different threads [message #30467 is a reply to message #30465] Mon, 03 January 2011 09:17 Go to previous message
koldo is currently offline  koldo
Messages: 3354
Registered: August 2008
Senior Veteran
Thank you Mirek

This
Quote:

INTERLOCKED_(mtx) {
}
is exactly what I wanted! Smile


Best regards
Iñaki
Previous Topic: OpenMP
Next Topic: Different native pthread.h implementations
Goto Forum:
  


Current Time: Thu Mar 28 11:41:41 CET 2024

Total time taken to generate the page: 0.01521 seconds