Introduction to semaphores in C

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in today's video we're going to take a look at a short introduction to semaphores and what do they actually do so here i have a simple program as we've seen this program time and time again in this uh series well i'm just creating a few threads namely four using this routine that they're calling and then i'm also gonna be joining them in here now uh first things first we're gonna go over how to use a semaphore and then we're gonna take a look at how exactly it works so to use it what we have to do is first include here the semaphore dot h header and in here we're gonna define a same underscore t type variable called let's call it just semaphore but usually if you're using semaphores you should call them something more specific here's just a simple example now to initialize this uh semaphore what we have to call it's called seminate and this guy takes in the reference to our semaphore variable that we've defined up top like so and then takes in a second parameter that tells the semaphore whether we are using multiple processes really so if you have only multiple threads then you should pass in here zero if you have multiple uh processes that have multiple choices use this semaphore then you should pass in here one uh here we're gonna pass it zero because we're only having this main process and uh no other one so you can just pass it here simple enough and then the third parameter is the initial value of the semaphore we're gonna see exactly what that value is all about i'm gonna pass in here just one okay important thing to note here is that semaphores do actually have an integer a value that is stored uh in their uh structure next up we're gonna have to destroy the same with the semaphore so i'm gonna call here send destroy just like most other uh objects in the p thread and similar libraries so here we can call in again semaphore and that just takes in the address to that semaphore that we want to destroy and that's it this tells the library that we're done with this enough for we don't need to use it we can free some resources so so far so good now there are two operations that you can do on a semaphore inside that right namely you can wait and post and a weight is very similar to a lock on a mutex and a post is very similar to an analog on a mutex but we'll see exactly the difference is once we get to the program itself what i'm going to do here is simply going to say uh let's say i just want to print a message so print f hello from thread let's say percent d and the back society i'm going to get i'm going to give it here the as argument i'm going to give it the id so i'm going to have here this args be passed um it's id inside peter creates i'm going to have pin pointer a equals emma lock of size of hint and then at the address of a save i and i'm passing here as a fourth parameter as we've learned before to our routine here then we're going to have the i value inside our arms then we can actually dereference it so i'm going to say pointer args like that and of course free that memory so right now we're not using in any way shape or form semaphores right if i try to launch this like so we're simply going to get four hellos from one from each trend so that's to be expected now uh let's say that we do something else like behind the scenes that takes in a long time so we're gonna just sleep with one second in this place we're gonna have to implement anything here and if i try to launch this again we're gonna just see four hellos at the same time printing our screen just with one second delay so nothing really special here but what if we before sleeping what if we wait on that sigma for what we should do same weight on this semaphore and then once we're done printing we do sam post on this semaphore okay let's see let's see what happens if i try to launch this you will notice that now every hello comes at a distance in time of one second right so only one thread can execute this part of code at a time it acts kind of like a mutex if you uh if you noticed so it is a very interesting behavior now let's take a look at exactly what happens with this semaphore behind the scenes and how these all wait and post actually works first things first there are a couple of rules to these same weight and same posts the same weight is going to check the semaphore's value if the semaphore's value is zero and it can no longer be decremented then the sema for the the thread itself is going to wait on that semaphore okay if it's higher than zero let's say five then it's gonna just decrement it and not wait just start executing the next lines of code okay and then same post sort of does the reverse so instead of decrementing from five to four let's say it increments it from four back to five once it's done executing and doesn't wait or anything you just increment it this is the idea of semaphore you have an integer and you either decrement that integral or increment it and if it's at zero you're gonna have to wait on it now let's take a look at our semaphore so here on the left we have the threads and below we have the sigma force value as i said in the beginning we're starting with the uh semaphore at one okay that's fine so let's suppose that one of the threads let's say thread zero uh calls same weight so treasure coil same weight i'm gonna denote that with an arrow down for decrementing right the weight operation might also be denoted with p of s uh that's also another way to uh say weight at that semaphore and well the first thread right zero is going to decrement this value from one to zero now all the other free threads are gonna also call same weight because they are multi-threaded they're all working at the same time uh now because the semaphore is at zero we're not gonna get anything so it's just gonna wait until semaphore is some number that's higher than zero all right that's gonna wait and that straight zero is gonna actually what it's gonna sleep for one second after one second it's gonna print it on the screen like we saw uh on the like we saw there and it's also gonna increment the value once it hits same post so now the value of the semaphore is one and it's going to finish this execution kind of three arguments and finish execution and we're done with that right we only have three threads now now all three threads are waiting on the same weight but only one is gonna be able to actually execute again so one is gonna start executing it's gonna decrement semaphore again from one to zero and it's gonna have to make the other threads continue waiting okay so that one this is let's say it's thread one but it could be any thread really let's say it's red one for this example it's going to sleep for one second it's going to print it on screen and it's going to increment the uh semaphores value again back to one okay and then same thing for the thread two it's just gonna decrement it again sleep print and then of course increment it and then for the last thread it's going to decrement the semaphore sleep print and then of course increment incremented and at that point we are done now the most important thing to note here is that between uh a weight and a post that's what it that's what is the critical section that we're trying to execute and you might notice that in this setup at every point all the code between a weight and a post is executed by just one trend this is why we actually got a message every second right because one second it would be the first strat then the second thread the second second and so on and so forth so this sort of acts like a mutex okay but there's a key difference here and i'm going to go back to the code here and instead of having it initialized to 1 we can change this to a 2. if we change this to a 2 and launch this you're going to see a very big difference in that well now two of the threads start running and then the other two start running again next second why is that well now because the value is two if we take a look at the table again uh so the initial value of the semaphore is two that means that well let's say thread zero hits same weight and it says okay well the semaphore is two we can decrement it so it's gonna uh decrement it but then let's say trade one sees that also the semaphore is not zero it's actually one still so it can also decrement it so both of them actually decrement or weight past the same weight call which make them actually print something on the screen at the same time after waiting one second and then once they're done they both increment this value so one trill is gonna increment it from zero to one and the other one is going to increment it from one to two and then because uh after that only two trends are left executing of course both of them are gonna be able to execute the same code at the same time because the semaphores value is two it's not just one so both of them gonna be able to wait or to pass the same weight call at the same exact time so this is why we're getting this behavior and of course if i change this to let's say a three three we're gonna see that free threads start executing at the same time and then lastly just one thread is gonna finish execution and you can do this with four if you want and then you're gonna have all the threads um executing at the same time and that's gonna be that so this is what semaphores are just basically sort of a mutex with a counter on it but the main difference between it and that recursive mutex that we looked at is that you can actually have it lock multiple times but between multiple threads right so we had two of the threads actually same weight past the same weight call at the same time and then they actually called sam post also at the same time whereas with mutexes you cannot have that even if we had recursive locks you could only lock a mutex in one single thread you could lock it twice in the same thread but you cannot lock it twice on different threads this is the very basic difference between semaphores and mutexes and that's all we have for this video i'm going to take a look at a couple practical examples regarding semaphores uh in the next lessons simply because i don't see much uh of them around and it's very difficult to wrap your mind around why they are useful why do you want to wait on the same resource multiple times so we're going to take a look at that in the next lessons i have got something out of this video if you do have any questions leave them down in comments below or on our discord server again the source code can be found on our website link in the description below take care bye
Info
Channel: CodeVault
Views: 17,982
Rating: 4.9808307 out of 5
Keywords: codevault, c (programming language), semaphores, system v, sem_init, introduction
Id: YSn8_XdGH7c
Channel Id: undefined
Length: 12min 24sec (744 seconds)
Published: Mon Dec 28 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.