 so let me continue and let's jump on semaphores you can find the semaphore objects these have several different flavors what the semaphore is and how it works let's imagine you have got a parking lot for example avis rental car this parking lot has three spaces for car number one car number two and car number three in the binary example we have got a parking lot for just one car but when you come and what you want to take the car from this parking lot the parking lot is initially empty so if you want to do something with the car you have to wait until somebody puts the car in the parking lot and then you can take it so the semaphore effectively can stop you from taking the car if the car is not on the place the semaphores when you define them have an empty parking lot so there is nothing and to be able to take the car from this parking lot somebody else has to give you the semaphore has to give you the car into the parking lot so the binary semaphore is a simple flip-flop telling you whether there is an item and you can take it if it is there you can't you are blocked if the car is not in the parking lot so you can see there exist two different functions one OS semaphore wait that causes the appropriate task to wait until there is something in the parking lot there is as well a function called OS semaphore release that gives the car back to the parking lot so typically you can use a binary semaphore in the way where you are waiting for some event for something to happen and when this happen some other task gives you releases the semaphore so this way you are able to get synchronized when something else happens this is as well a very useful thing when you operate with the interrupts our TCP IP stack is based on this mechanism and when you receive a packet you get an interrupt and this interrupt gives the semaphore so releases it and the task waiting for the packet within the TCP IP reception loop will take the semaphore and it will process the data guarded by this mechanism so OS semaphore release gives the car to the parking lot and allows other tasks to operate with that and OS semaphore wait take the car from the parking lot and leave it empty that's how the binary semaphore works so this is the case of a binary semaphore with the semaphore present if task 2 awaits for the semaphore originally there is nothing no car in the parking lot so the task 2 is blocked blocked blocked task 1 then releases the semaphore so it gives it to the parking lot and the task 2 because it waits for it and the semaphore gets present it will take it away process it and in the next loop it will again wait for the new semaphore technically this is implemented as a list of one item length we can create the semaphore with the OS semaphore create wait for it with a specified timeout and we can as well release the semaphore with the OS semaphore release it's a very effective synchronization mechanism it can be used among different tasks both on the side who releases the semaphore and on the side who waits for the semaphore because then the tasks can compete for the semaphore the counting semaphores are something that gives you more possibilities so if I define a counting semaphore I am defining how big the parking lot is so I can for example define three or five elements and this is the maximum number of cars I have available so with the counting semaphore I can release as many as five cars and place them into the semaphore and when I take the semaphore I can take as many as they are available but maximum five at a given time this is one big advantage because again in case of a web server for example where you have a need for several different threads serving different content in parallel this helps you to distribute the load because whenever you get an HTTP request you put one semaphore in the queue and if any handler task is available it can take it but by number of elements that are available maximum five you can spawn maximum five tasks providing different data to you so if you define a memory just for five tasks the semaphore counting semaphore can limit how many of the threads will be available so it can limit how much memory you spend on sending these HTTP data another thing is if you for example allocate the different yards for communication or blocks of memory so the counting semaphore can help you to limit the number of resources up to a given given amount and not more you can define the counting semaphore with account value and again you can wait for the standard semaphore with a timeout and you can release the semaphore and in case there are spaces in the parking lots the semaphore release will return okay but if it doesn't fit inside it will report an error because the parking lot is full in this case I can use two different tasks that release the semaphore so both of them put their own cars in the parking lot and then the task three can consume them one by one but if you would have more tasks just two of them could request any functionality at the same time from task three the counting semaphores are typically useful when you need to limit but still define how many elements in parallel can be taken executed provided