What is a mutex in C? (pthread_mutex)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so we left at this issue where we have a race condition for writing to the males variable if we launch this again of course we're going to get a different number than 2 million which is what we would expect if we would just do everything in one thread now we know why that is but in this video i'm going to talk about how to solve this issue an answer is using a mutex this is how you can solve the issue a mutation is sort of a lock around a section of code so to speak so for example what we could do is let's say have a variable called lock set it to zero and set it to one whenever you're doing something and set it to zero whenever you're done doing something okay and before all this check if the lock is already one so if the lock is already one right before you are trying to set a locked one then you should sort of wait until the lock is zero this way uh what would happen is that if a thread tries to actually increment the males variable well it certainly will increment it but it will also set the lock to one so if the second thread comes in at the same time and tries to increment it it's gonna stop at that condition because the lock is gonna be set to one so only after we're done incrementing it's gonna be reset to zero so then the second the second thread could come in and read increment and write in the right order right so nowhere you would have a thread that just starts reading and then the other thread will start executing like we had in that example i showed you the race condition right so in the race connection we had a read and then the thread got paused for whatever reason and then the second that came in and started to read increment right like seven times and then this guy had inside its memory said its cpus registers the old value right which was then written to the memory like this we can prevent it but how do we wait until the lock is zero well we don't really have to implement our own variable with log things and whatnot the pthread the posix thread api actually has something like that implemented that we can already use and it's much safer than what we would do here so to start using it so we're gonna remove this lock variable we're gonna replace it with a p thread underscore mutex underscore t and call it let's say mutex for now for simplicity's sake okay so we have a mutex and well before we can use it we have to initialize it so to initialize it we go down here and let's say we initialize it before creating the thread of course i'm going to say pthread mutex init right and this guy takes in just two arguments the address to that mutex i'll just add mutex and then some attributes which we're not going to get into right now so those those can be set to null and it's going to be all right so just set everything basically when we pass here no it's going to set everything to default and that's all right for us and of course with an init comes with it comes with a destroy so we're going to have to also destroy the memory that's been allocated here so i'm going to call peter mutex destroy and this guy just takes in the address to the mutex no more second parameter right so pictured mutex init with the mutex and then destroy and now we have the mutex available to us we haven't used it yet in any way shape or form we just initialize it now let's go to actually using it so here these three operations so checking if the lock well has been locked has been taken by someone some tread and waiting until that uh lock is unlocked and also setting to one the lock once we're done doing all that is being accomplished with just one function and that function is called pthread mutex block so lock all it takes is just a reference to our mutex and that's it so this just this one function does all that for us so we don't have to care about waiting and not waiting and finishing waiting for all that now in place of this operation setting our lock to zero basically unlocking the mutex is just the call to pthread mutex unlock as you might have guessed and we just pass in the mutex and that is it my friends all you have to do is just call lock and unlock and all of a sudden the result is going to be correct so now if we try to launch this it's going to take a bit longer but we do get the right result 2 million right 2 million even though we have incremented it a million times and it's in a multi-threaded context it works and we can even increment it more times like let's say 10 million and it's still going to work it might take a bit longer but it is still going to work there you go that is 20 yeah 20 million so what does this do actually well this locking and unlocking of mutexes is basically protecting think about it as sort of some brackets between a part of a code that you want to protect to protect against what protect against other threads executing it at the same time so if at any point a thread is executing this this line of code there's not gonna be any other thread that's gonna execute this same line of code simply because there's a mutex around it if we didn't have the mutex we didn't have this we wouldn't have this um certainty and then we could get into race conditions of course not all the time not all instructions have to be like that because if all instructions are going to be executed only by one thread at one point in time might as well just have one single thread executed yellow right now the idea is that we want in this case correct data and this program on its own doesn't do anything useful so it's just a good example so that you understand what's going on behind the scenes and why mutexes are needed and before anyone asks this actually works with more than just one thread so if i for example try to create two more threads let's copy and paste this and i'm gonna initialize here p3 and p4 and this case going to be p b 4 p 3 okay and then i'm going to join it two more times so let's say p3 and p4 here and guess just for correctness sake let's do it let's give it a different uh error number everywhere not really a big deal but just to be safe and now if we try to execute with four four threads you'll notice that we are gonna get a pretty long wait time but we're gonna get a result of 40 million without those threats that result probably would have been in the 20 million let's actually check and see if i try to launch this without the locks and unlocks as you can see it's one or it's 15 million so that was a pretty bad result if we didn't use stress but notice it was faster so it is much better to use to do not use mutexes whenever possible but in this case we kind of have to it's just an example you'll see in the future exactly when to when and why to use mutexes now one more thing that i forgot to mention is that a race condition can only occur on a multi-core processor if you have a single core processor then it's very unlikely that you will encounter a race condition but as nowadays most like 99 of the cpus out there are multi-core even though low powered ones you are going to encounter this okay that's about it for today thank you so much for watching if you have any questions leave them down comments below or on our discord server of course the source code of today's video will be also down in the description below on our website thank you so much for watching and take care bye
Info
Channel: CodeVault
Views: 19,010
Rating: 4.9940829 out of 5
Keywords: codevault, c (programming language), mutex, race condition, pthread
Id: oq29KUy29iQ
Channel Id: undefined
Length: 9min 18sec (558 seconds)
Published: Fri Dec 11 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.