Click to See Complete Forum and Search --> : working with locks/critical sections
Mal Reynolds
November 20th, 2008, 11:49 AM
I have done a bit of multithreading before, but it has never been a situation until now where i have needed to actually synchronize the threads. As I have very little experience working with thread sync I had a few questions.
I have read the msdn pages on the win32 critical section functions, and basically understand how to use them. before i started using the win32 functions though, i had tried this:
#define LFS_LOCKED !!( logfstream::properties & LFSTREAM_LOCKED )
#define ENTER_LFS_LOCK_ while( LFS_LOCKED ){ } properties |= LFSTREAM_LOCKED;
#define EXIT_LFS_LOCK_ properties &= ~LFSTREAM_LOCKED;
where 'properties' is just a static int.
essentially, i realize now, that it is similar to a critical section with infinite spin count. although i had no problems when using the above code, my question is... what problems could there be using it, or is it viable code to use for thread sync?
ps - if i wrote some kind of wrapper for this that would sleep/activate threads and act as a true thread sync object, would that be ok, or is this something that the operating system HAS to handle to truly prevent any thread problems (i.e. don't bother trying, just use win32)?
TheCPUWizard
November 20th, 2008, 11:51 AM
Well for starters it is not thread safe..:eek::eek:
Two threads could each read the current state, detect that it is "not locked" and them both attempt to lock the section an proceed on their merry way to disaster.
Mal Reynolds
November 20th, 2008, 12:31 PM
certainly! thank you for pointing that out :) how, though, would I prevent that from happening, or is it necessary for this kind of thing to be done on the OS level?
TheCPUWizard
November 20th, 2008, 12:42 PM
certainly! thank you for pointing that out :) how, though, would I prevent that from happening, or is it necessary for this kind of thing to be done on the OS level?
Using the built in (proven) functionallity would be a good starting point. [I am alsways curious why people feel the need to "roll-their-own" before having a full understanding and practical experience with the existant proven solutions:confused::confused::confused:].
FYI: It does NOT have to be done at the OS level.
Mal Reynolds
November 20th, 2008, 03:24 PM
well, for me at least, i like to know how things work, and by writing my own i understand how they work. i.e. i wouldn't really ever write code for another list again when there is the STL, but when i was learning i did, to understand how it worked. but yes, i am using the win32 functions for the actual project, I was just trying to learn more about how they worked. :wave:
Lindley
November 20th, 2008, 04:08 PM
The simplest possible type of mutex lock would use a "test-and-set" assembly instruction. That's the key: That both the test of the state and the modification of the state be done in the same instruction, to insure another thread couldn't take over between the two.
"Spinlocks" may actually be implemented this way on some systems. In most cases, of course, it's better to use a solution that gives up the CPU when it cannot proceed so you don't waste cycles.
Lindley
November 20th, 2008, 11:00 PM
It should also be noted that threads implemented on the user level (as opposed to the kernel level) have a significant disadvantage: If one thread is suspended for a kernel-level task (such as disk IO), *all* threads will be suspended with it.
Of course, there are also disadvantages to purely kernel-level threads, mainly that kernel calls are more expensive than functions which stay in userland.
Most threading packages provide a good compromise between the two schemes, and precisely what that compromise is has been researched quite a bit, so you may as well make use of the results.
egawtry
November 21st, 2008, 10:16 AM
I am surprised that no-one mentioned it:
Take a look at InterlockedExchange.
-Erik
Mal Reynolds
November 22nd, 2008, 01:05 PM
wow, thank you, the InterlockedExchange may just be the ticket for what i'm currently doing. I am usually only changing a couple of static class variables so using the 'Interlocked' set of functions I should be able to avoid going through the trouble of Critical Sections just to change a couple of variables! :D
Mal Reynolds
November 22nd, 2008, 04:04 PM
just out of curiousity, would it then be viable to modify the defines in my original post as follows for a simple spin lock?:
long spinLock = 0;
#define ENTER_LFS_LOCK_ while( InterlockedExchange( &spinLock, 1 ) == 1 ){ Sleep( 10 ); }
#define EXIT_LFS_LOCK_ InterlockedExchange( &spinLock, 0 );
Lindley
November 22nd, 2008, 05:39 PM
Should be acceptable, yeah.
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.