In Golang, when multiple goroutines access shared state simultaneously, race conditions can cause inconsistent behavior that is difficult to debug; mutexes (synchronization primitives) ensure exclusive access to shared resources by allowing only one goroutine to read or write at a time, while atomic values provide a lighter-weight alternative for simple operations like counters or health values by guaranteeing atomic read/write operations without the overhead of mutex locking.
Mutexes and Atomic Values in Go: Synchronization Guide
Added:what's up everyone in this video I'm going to teach you everything you need to know about mutexes and atomic values in golang these are very important especially if you do distributed stuff or if you're going to use go routines that will modify and read from a state right before we continue you know the drill if you like the videos I'm providing to you consider subscribing because 50 of my viewers are still not subscribed to the channel and you can do me an enormous favorite subscribe to the channel jump into the Discord give me a thumbs up the Hoshi bang let's go all right so uh as usual we're gonna make as a very nice use case so I can show you a very good example I'm going to test that and I'm going to teach you some cool tricks so let's say we're going to make a game let's give it some dopamine and let's make a game so we're going to say type game it could be a game state or something client-side server side doesn't really matter actually we don't need that game let's make a player we're gonna make it play it it's going to be strict right because the game without a player that's uh not a good game so we have a plate and we're going to give this guy some health right and it's going to be an end and let's say we're going to make a new player real quick and that's going to be a pointer to this player thingy and let's return the player right just like this and um I'm gonna give this health and let's say 100 or something that's fine okay so in a game we always have uh some kind of a game State uh some game Loop actually that will do some calculations but the player is attacking he is whatever he's doing and you will have some kind of a UI that's what a reading that we'll keep reading from the player to show his health in the UI right that's a very common use case so let's make something like um start UI Loop and we're going to give this player inside of this thing I'm gonna give it the players and we're going to say here take it is going to be an um Time new take it we're gonna say time second like this we're gonna make a for Loop so we can print out display it um you're going to say fmt parental m uh players uh actually we're gonna do a print F real quick players health is going to be this percentage d slash R so we're gonna we're gonna print at the same line and we're going to say player Health like this and then we're going to wait for the ticket uh to complete and then we're gonna keep looping that's our UI Loop very simple it's gonna take in a player gonna read from the player right the next thing we're gonna do is gonna start the game loop we're gonna say start uh game Loop we're gonna paste in the players I'm gonna give it a player as an argument I'm actually going to do the same thing we're gonna copy the whole shebang we're gonna make a loopy but we're gonna say that the ticket is going to be a millisecond a millisecond times let's say uh 300 or something and in this Loop what we're going to do is we're going to adjust the players as health it's going to take some damage from I don't know he's getting shot at or something I have no clue or he's uh he felt in the lava or something and we're going to say that uh player is held minus equals uh is going to be a rant and and we're going to wrap a random number between 0 and 40 or something and now we're going to say that if the player health is going to be smaller or equal than zero we're going to break and we're going to fmt prevent f Alan I'm going to say game over a simple game like this right so in our main function what we could do very simple and I'm doing these examples because it's important I could already have something typed out for you but that's that's that's not a good case you're not going to learn as much as now uh so we're gonna make this place we're gonna say player is going to be a new player right and then we're gonna say I'm gonna start up the UI Loop in another go routine starts a UI loop with the players inside of it and then we're gonna block on the game Loop which will return actually uh if the player is held is um actually big we could um it's fine it's fine it's all fine all right so if we run this go run main.go then you see the player is held this uh boom and the game is over right it's game over and it's a little bit uh problem here because we have the Sprint the Sprint R here but it's fine you know you know the deal and it's work it seems to work perfectly fine right you make your program and you think everything is good and you make a test right so let's make a test here I already have a test open so we're going to say funk test game and we're gonna basically copy the whole Bank from our main paste it in heat right and then we could say something like go test verbose uh everything boom we're gonna test the game here real quick boom and everything is is done the test is passed and we are happy we go to home we set Margaritas on the beach but actually there is a big book you have a database condition and how can you actually test that well you can do that by saying go test uh you could the whole shebang and then you could do dash dash race my presenter so it's testing everything and then you see test field why because we have a database if you specify dash dash series at the end of your test golang the go compiler will spin up a race detector that can actually track most of the time very well if you have database conditions in your program and the data risk condition is basically that you have multiple go routines that are basically trying to read and right at the same time somebody's reading and somebody is writing so it basically means that there could be a possibility it's not always the case it's not always the case but most of the time it will look perfectly fine but there is a possibility that you will have inconsistent Behavior because the player health is 33 you're gonna read it but actually it's you see what they're not synchronized and it could be that you will have a wrong value so the player could already be dead or not that whilst he needs to be that if you know what I mean so very hard to track so very important to always test these things with a risk where there is detectors okay so now you're going to fix that right how do we fix that well there are two possibilities because I'm going to teach you everything about mutexes and atomic values let's let's start with the mutex so what you could do is basically heat we could say Amu from mutex is going to be a sync WR mutex and that's basically uh wrw mutex it's a read write mutex so we can basically look for reading and look for writing at a different time which is more optimized and just lock everything for writing and reading so we have a mutex heat so what we're gonna do here we are reading from the state right we are not updating the state in this UI Loop the UI is a reading from the states so we're going to say players airlock and here we're going to say player mutex um add unlock right that's fine so you look at before and you'll unlock it after you could also use a deferred but we're not going to do that because we're in a loop uh yes then our game Loop what are we doing here well here we are actually adjusting the state and here we are reading from the state so what we could do we're gonna basically lock the whole shebang so we're gonna say players AMU we're gonna lock because we're gonna read and write so we're gonna lock we're not only gonna gonna read we're gonna write also so we're gonna lock this thing and after we are done heat we are going to say um play it mutex unlock just like that and now we are actually protected so let's uh test this real quick so we're gonna attest to raise condition flag and you see the test is passing so what is a mutex a mutex is basically a synchronization way a synchronization utility uh let's say you have a couple of go routines and they are all waiting they all want to access and and and and they want to access read or write something the same variable from a state right so how are you going to determine who's gonna be first and who's need to wait well that's what the mutex is going to do you can you can think of it like somebody has a flag there is a buy a beautiful Delicious Pie in The Middle and there are 10 people in the line and they all want to eat from the pie that's a problem right so you need to synchronize and you can give them a red flag and only the guy with the red flag can eat from the pie and when he is done he can give his flag to the other guy so the other guy can can eat from the pie that's the same thing with the mutex right so everybody that holds the mutex can write depends on what mutex you you you uh you're locked can write and read from the state and only the root the only the routine where the flag can do that mathematics can do that and when it's done reading or writing it will give the flag to another go routine and that's the next in the line that can read and write from that state that's what a mutex is doing it's a synchronization way so you are 100 guaranteed that the the reading and writing is happening synchronized with the Synergy so there is no inconsistent Behavior right cool and you could also refactor this a little bit right instead of doing it dirty like we did we could say funk for example P player get health or something which is going to return an integer and we're going to say heat uh player emu get is basically read so we're going to say look and I'm going to say the third here we can do the third p and Moon uh R unlock right and then we're going to say return uh P held just like that and then we're gonna make another function it's going to be players uh take damage or something take damush value and I'm going to say p.m lock because we're going to adjust the state we're going to deferred also heat and it's going to be an uh uh unlock and then we're gonna say play it health minus equals is the value just like that and then instead of doing these crazy locks here we could just make it simple nice and clean I'm going to say get health and then here it's a little bit different let's delete the mute access first of all we're going to say play it take damage right and it's going to be this ran thingy and then here we're going to say FP get health uh and that should actually be the same thing let's test it real quick so a little bit of um yes a little bit of of a cleanup right so this is basically mutexes right very important to understand always use them always think about a use case that could have that that could be possible each time you think there are multiple go routines accessing Reading Writing from a seed as the same state variable think about a mutex test it with go with the test desk flag okay the next thing are Atomic values and let's refactor this let's delete the mutexes delete delete here so there are no mutexes anymore so if we test again we're gonna see boom risk condition detected right problem how are we going to fix that well let's use Atomic values so instead of making this health an end we're going to make it an n32 so if you want to get the health we're going to basically say that could be an interest no no problem you're going to say heat atomic uh is going to be a load entally tool and of course we need to cast this to an inch because this is an n32 but we are going to return inst for user friendliness so we need to cost this in32 to an end so we're going to load the address right the address of player health that's what we're gonna loot right so an atomic value is basically um an optimized it's it's basically it's you Atomic basically means that you can do an operation one at a time uh and that's what this this is going to do it's it's going to make sure that everybody that's going to read that's going to load the end and it's going to store the end that it's going to be in a synchronized way and it's for some of the use cases it's much better to use an atomic end especially for these simple things like a health and all that stuff uh because it's going to give you less overhead and complexity that comes with a mutex and if you want to be more precise because I'm going to be very careful with what I say about these things because the people on Reddit try to Pitchfork me and every mistake I make so if you want to learn more about Atomic end you can go to chat uh GPT GPT 3 chat and it will tell you everything what you need to know all right so get help uh take damage is a little bit different so what you're going to do is first of all you're going to get the health it's going to be I think we could do get health like this right so you're gonna load this int and then we're gonna say p atomic store n32 and we're going to store the can we do we're gonna store it at the address of the player Health right and then we're going to store the result and that's going to be Health minus value and that's going to be a problem because it needs to be an entity two so we're going to say n32 this thing and we don't need to do anything more because we have these nice abstractions about get health and take damage and I think if everything is fine and we're going to test this with the risk condition it should be fixed boom yes so you see that is basically um how to use mutexes and atomic values to protect your application from these conditions and consistent Behavior very hard to track it's gonna work from 80 times of 100 it could be that your application is perfect but it's the 10 times that's going to be an inconsistent State and if you're doing a very important Shenanigans with user balances or or points or something yeah you don't want to have that so always be careful with that it's um the most annoying thing to debug is going to take a lot of time so be aware of that right so that's it if you have more questions hey feel free to jump into my Discord Community uh overs I think we are about 600 people already so uh if you have questions jump into the Discord Community give me a thumbs up subscribe to my channel and I'm looking forward to see you in one of my live streams or future videos peace out
Up Next

GopherCon 2017: Understanding Channels | Kavya Joshi
@GopherAcademy
129.1K views•2017-07-24

BitTorrent Protocol Explained: Piece Selection & Peer Choking
@StevenGordonAU
481 views•2013-02-22

HTTP Requests Explained: GET, POST, PUT, DELETE
@codecademy
103.1K views•2021-10-07

Enigma Machine Mechanics: WWII Encryption Explained
@JaredOwen
13.2M views•2021-12-11
Related Study Plans & Knowledge Roadmaps
Structured learning paths in Computer Science


















![[POPL2021: Tutorial] Dynamic Data-Race Prediction: Fundamentals, Theory and Practice](https://i.ytimg.com/vi/5AZIQFeluIY/maxresdefault.jpg)

![Golang: Evita errores en concurrencia [Condiciones de carrera, Mutex y WaitGroup explicado]](https://i.ytimg.com/vi_webp/Wgbs8HbBV_U/maxresdefault.webp)















