Mutext?
BlitzMax Forums/BlitzMax Beginners Area/Mutext?
| ||
I 'm trying to understand the mutex , but I do not succeed, I do not see the difference in the console about it. Any suggestions ? SuperStrict Global Mutex:TMutex = CreateMutex() 'create the mutex. This mutex will be locked anytime a thread needs access to the consol Function Hello:Object(data:Object) 'LockMutex(Mutex) 'Lock the mutex so we can have exclusive access to the consol Print "Hello 1" Print "Hello 2" Print "Hello 3" Print "Hello 4" Print "Hello 5" Print "Hello 6" 'UnlockMutex(mutex) 'unlock the mutex to allow other threads access End Function Function GoodBye:Object(data:Object) 'LockMutex(Mutex) 'lock the mutex blah blah Print "Good bye 1" Print "Good bye 2" Print "Good bye 3" Print "Good bye 4" Print "Good bye 5" Print "Good bye 6" 'UnlockMutex(Mutex) 'blah again End Function CreateThread(Hello,Null) CreateThread(GoodBye,Null) Delay(1000) 'delay to allow threads to finish |
| ||
There is nothing happening because it finishes printing "too fast"SuperStrict Framework Brl.StandardIO 'for print Import Brl.Threads 'for mutex Global Mutex:TMutex = CreateMutex() 'create the mutex. This mutex will be locked anytime a thread needs access to the consol Function Hello:Object(data:Object) 'LockMutex(Mutex) 'Lock the mutex so we can have exclusive access to the consol For local i:int = 0 to 10 Print "Hello Hello Hello Hello Hello" + i Next 'UnlockMutex(mutex) 'unlock the mutex to allow other threads access End Function Function GoodBye:Object(data:Object) 'LockMutex(Mutex) 'lock the mutex blah blah For local i:int = 0 to 10 Print "Bye Bye Bye Bye Bye Bye Bye Bye" + i Next 'UnlockMutex(Mutex) 'blah again End Function CreateThread(Hello,Null) CreateThread(GoodBye,Null) Delay(1000) 'delay to allow threads to finish Mutexes disabled. See how both threads break the output of the other thread? Hello Hello Hello Hello Hello0 HBello Hyeel Blyoe BHye Byee lBlyoe Bye BHye Byee0 l lo Bye Bye Bye Bye Bye Bye Bye Bye1 Bye Bye Bye Bye Bye Bye Bye Bye2 Bye Bye Bye Hello1Bye Bye BHello Hello Helyel oBye Bye3 Hello He ll Bye Bye Bye Bye Bye Bye Bye Bye4 Bye Bye Byeo2 Hello Hello Hello Bye Bye Bye HByee Byle5l Bye Bye Bye Bye Bye Bye Bye Bye6 Byo Hello3 e By e HelloBye B ye HBeyel Bye lBye Boye7 HBye Bye Bye Bye Bye Bye Bye Bye8 eBye Bye Blye Byle Bye oBy e ByeH Byee9 lBye Bye lBye oBye Bye Bye BHye Beye10 llo4 Hello Hello Hello Hello Hello5 Hello Hello Hello Hello Hello6 Hello Hello Hello Hello Hello7 Hello Hello Hello Hello Hello8 Hello Hello Hello Hello Hello9 Hello Hello Hello Hello Hello10 And this happens when enabling the mutexes: Hello Hello Hello Hello Hello0 Hello Hello Hello Hello Hello1 Hello Hello Hello Hello Hello2 Hello Hello Hello Hello Hello3 Hello Hello Hello Hello Hello4 Hello Hello Hello Hello Hello5 Hello Hello Hello Hello Hello6 Hello Hello Hello Hello Hello7 Hello Hello Hello Hello Hello8 Hello Hello Hello Hello Hello9 Hello Hello Hello Hello Hello10 Bye Bye Bye Bye Bye Bye Bye Bye0 Bye Bye Bye Bye Bye Bye Bye Bye1 Bye Bye Bye Bye Bye Bye Bye Bye2 Bye Bye Bye Bye Bye Bye Bye Bye3 Bye Bye Bye Bye Bye Bye Bye Bye4 Bye Bye Bye Bye Bye Bye Bye Bye5 Bye Bye Bye Bye Bye Bye Bye Bye6 Bye Bye Bye Bye Bye Bye Bye Bye7 Bye Bye Bye Bye Bye Bye Bye Bye8 Bye Bye Bye Bye Bye Bye Bye Bye9 Bye Bye Bye Bye Bye Bye Bye Bye10 There are many chances it "with pure luck" works without Mutexes - but there is no guarantee. So best is to use these mutexes for such scenarios. bye Ron |
| ||
Here disable Mutex.Building Inicio Compiling:Inicio.bmx flat assembler version 1.69.14 (1819004 kilobytes memory) 3 passes, 2634 bytes. Linking:Inicio.debug.mt.exe Executing:Inicio.debug.mt.exe Hello Hello Hello Hello Hello0 Hello Hello Hello Hello Hello1 Hello Hello Hello Hello Hello2 Hello Hello Hello Hello Hello3 Hello Hello Hello Hello Hello4 Hello Hello Hello Hello Hello5 Hello Hello Hello Hello Hello6 Hello Hello Hello Hello Hello7 Hello Hello Hello Hello Hello8 Hello Hello Hello Hello Hello9 Hello Hello Hello Hello Hello10 Bye Bye Bye Bye Bye Bye Bye Bye0 Bye Bye Bye Bye Bye Bye Bye Bye1 Bye Bye Bye Bye Bye Bye Bye Bye2 Bye Bye Bye Bye Bye Bye Bye Bye3 Bye Bye Bye Bye Bye Bye Bye Bye4 Bye Bye Bye Bye Bye Bye Bye Bye5 Bye Bye Bye Bye Bye Bye Bye Bye6 Bye Bye Bye Bye Bye Bye Bye Bye7 Bye Bye Bye Bye Bye Bye Bye Bye8 Bye Bye Bye Bye Bye Bye Bye Bye9 Bye Bye Bye Bye Bye Bye Bye Bye10 Process complete Enable Mutex. Building Inicio Compiling:Inicio.bmx flat assembler version 1.69.14 (1814975 kilobytes memory) 3 passes, 3080 bytes. Linking:Inicio.debug.mt.exe Executing:Inicio.debug.mt.exe Hello Hello Hello Hello Hello0 Hello Hello Hello Hello Hello1 Hello Hello Hello Hello Hello2 Hello Hello Hello Hello Hello3 Hello Hello Hello Hello Hello4 Hello Hello Hello Hello Hello5 Hello Hello Hello Hello Hello6 Hello Hello Hello Hello Hello7 Hello Hello Hello Hello Hello8 Hello Hello Hello Hello Hello9 Hello Hello Hello Hello Hello10 Bye Bye Bye Bye Bye Bye Bye Bye0 Bye Bye Bye Bye Bye Bye Bye Bye1 Bye Bye Bye Bye Bye Bye Bye Bye2 Bye Bye Bye Bye Bye Bye Bye Bye3 Bye Bye Bye Bye Bye Bye Bye Bye4 Bye Bye Bye Bye Bye Bye Bye Bye5 Bye Bye Bye Bye Bye Bye Bye Bye6 Bye Bye Bye Bye Bye Bye Bye Bye7 Bye Bye Bye Bye Bye Bye Bye Bye8 Bye Bye Bye Bye Bye Bye Bye Bye9 Bye Bye Bye Bye Bye Bye Bye Bye10 Process complete I am confused. |
| ||
Ok, no problem, I was looking at the output of the debugger, but the executable and msdos window you can see the difference. Thanks You. =)![]() |
| ||
Ok, I will try to explain what they have learned if I touched taught; arle to someone else. The mutex is like what I have on my TV where if I press down drastically the volume of the TV. So the threads are like every person who pulls in a room, for example, if two people speak at the same time do not understand anything, so when a person listens to the other, that's mutex, and when he begins to speak the otre person enters mutex. =) I'm right? |
| ||
A more computing oriented example: Two processes may change a certain value, perhaps the amount of money in an account. Let's say the value is now 10, and each process tries to add 1. If they operate in sequence then one process will read the value 10, add 1 to get 11 and write that new value. The other process will read 11, add 1 and write 12. But if they can operate in any uncontrolled order we may have First process reads a 10. Second process reads a 10. Each process adds 1 to get 11. Each process writes 11 as new value. So the end result is 11 when it should be 12. There must be some mechanism by which a process declares that it will access the value. Everyone else is then excluded from doing the same until the first process is finished and declares it is done. That is mutual exclusion. |
| ||
One more comment. This can be very hard to debug. In the example I just gave there is an error only when there is conflict between two processes operating at almost exactly the same time. The program might run flawlessly the first thousand times and then suddenly fail. |
| ||
thanks Floyd, A simple example of semaphore ? |
| ||
Google "BlitzMax semaphore": https://en.wikibooks.org/wiki/BlitzMax/Modules/System/Threads#CreateSemaphore bye Ron |
| ||
Thanks you Derron. This really is very confusing to me, I'm reading some articles that talk about a public restroom where a single user can use it, for mutex, then I read another article about philosophers eating at a table with some forks, where if you have a fork can eat and the other has to wait where in the end one can starve. So my brain is trying to absorb all this in the best way possible. Or other item of a barber , the barber's chair and chairs waiting for customers. this is crazy. |
| ||
Semaphores... I find some examples with multithreading are difficult to understand too. Simple explanation - a semaphore is a value than can make a thread wait when its value is 0 when any thread calls WaitSemaphore. If the value is non zero and WaitSemaphore is called then the value is decremented -1 and the thread continues. If a PostSemaphore is used the value is incremented +1 and the thread will always continue. That's *all* it does. Same explanation... Start it with a value, any positive value. Every time you call PostSemaphore then the value will increment +1. Everytime you call WaitSemaphore then the value will decrement -1. When the value gets to zero and a WaitSemaphore is called then WaitSemaphore will wait until the value is more than 0 and will then decrement again. Now to know any thread can safely call WaitSemaphore and Postsemaphore without any problem with updating its value. EDITED:- Some examples to help understand, use the Debugger to step through the code and you can see where the thread is forced to wait. You will need to exit via the editors debug STOP icon when the program enters a wait state. ' create a semaphore with a value of 2 Local sem:TSemaphore = CreateSemaphore(2) DebugStop WaitSemaphore sem ' sem value is now 1 and the thread continues WaitSemaphore sem ' sem value is now 0 and the thread continues ' The thread will wait at the next WaitSemaphore because the sem value was 0 previously. This thread will wait until another thread 'PostSemaphore sem' to make the sem value +1. WaitSemaphore sem ' this next line cannot be reached until another thread PostSemaphore sem! There are no other threads so we need to exit via the editor debugger icons Local oops:Int Another example with single thread ' Try this example and step through ' create a semaphore with a value of 2 Local sem:TSemaphore = CreateSemaphore(2) DebugStop WaitSemaphore sem ' sem value is now 1 and the thread continues PostSemaphore sem ' sem value is now 2 and the thread continues WaitSemaphore sem ' sem value is now 1 and the thread continues WaitSemaphore sem ' sem value is now 0 and the thread continues ' The debugger will stop at the next instruction because the sem value was 0 previously - youll need to exit the program via the Stop icon in the editor WaitSemaphore sem ' this next line cannot be reached until another thread PostSemaphore! There are no other threads so we need to exit via the editor debugger icons Local oops:Int Now imagine that other threads can postsemaphore and waitsemaphore too. |
| ||
A "real world example" of what col described is: there is a bar, with a barkeeper filling glasses with beer. He fills one and starts with the next. Each time he filled a glass, the amount of glasses on the table increases ("PostSemaphore"). Then there are the guests, they want beer. They order a beer ("WaitSemaphore) and if there is a beer on the table, they are able to take it without waiting time. But if there is no beer left on the table, they need to wait until the barkeeper filled a new glass ("PostSemaphore"). What could you do with it? you could let one task create things which another task processes. The semaphore allows to have multiple task process these things. @ fork and starving people Yes, the Mutex restricts usage to a single user. Nobody else is allowed to do something in the mutex-part of your code. it is exclusive for that moment. bye Ron |
| ||
@Col Thanks Many thanks col , that very simple explanation has come at a better time , my brain is very simple and is often confused with programming techniques. @Derron Thanks Yuo too. |
| ||
wth is mutex anyway .. |
| ||
Mutex is short for 'Mutual Exclusion'. To be mutually exclusive means there can be only 1. Think of a mutex as a variable that can be put into a locked state. Any thread can put a mutex into a locked state by using LockMutex. You then must unlock the mutex using UnlockMutex from the same thread. When a mutex is in the locked state and another thread calls LockMutex on that mutex then that 'newer' thread is forced to wait until the same thread that locked the mutex unlocks it. When it becomes unlocked then the waiting thread will be allowed to continue executing instructions. |