 Hi everyone, today we will learn about condition variables. So I have written the code for the producer-consumer problem that you have seen in the lectures. So let's open this code in using code. So here I have just included some libraries. So let's first see what all is there in this program. We have a buffer which will store pending requests that are to be consumed by the consumer. So we have written this consume request function that will take out requests from the buffer and consume them one by one. Also this produce request function will add requests to the buffer when the buffer is empty. So we have two threads. First thread is the producer thread which runs this produce request function and another is consumer thread which runs this consume request function. So let's see what all variables are there. So first is the count variable. This variable stores the number of pending requests that are there in the buffer currently. This denotes the total number of requests that will be added by produce request function to the buffer and then we have maximum buffer size. So our buffer is bounded which means that we cannot have more than max buffer size number of requests in the buffer. So if let's say max buffer size is 5. That means that our buffer can only store 5 pending requests at a time and if produce request want to add more requests to the buffer it needs to wait for the consumer to consume some request and only then it can add more requests. So let's go through the code. I'll first go through the main function. So we initialize count with 0 and here we just take two arguments. Number one is the total number of items that we want to produce and second is the maximum buffer size. Then we use the malloc function to allocate an integer array of size max buffer size. Then we have two threads producer and consumer thread as discussed earlier and we call the pthread join function on both the threads so that the main thread waits for both the threads to finish and finally we free the buffer that was allocated and return 0. So let's have a look at produce request and consume request function. So this is the produce request function. Here we iterate total item number of times and in every iteration we will produce one item and put it in the buffer queue. Before putting in the buffer queue we need to check if the buffer is already full and if it is so then we need to wait for the consumer. We have two condition variables here one is space available and another is items available. So let's say consume request function is executed first. Then what will happen here it will first lock the mutex as discussed in the lectures it is necessary to hold a lock whenever you are checking for condition because we do not want the computer to context switch after checking the condition otherwise there will be a miss signal. So it will acquire the lock then it will check if count is 0. Now count is equal to 0 means that there is no item in the buffer. So consume request cannot consume request because there are none in the buffer. So it needs to wait for the items available condition variable and it will also pass the mutex. So this function will release the mutex and this will cause this thread to sleeve. Now the produce request function will have to execute and here it will also acquire the mutex and it will check if count is equal to maximum buffer size which is not the case because initially count is 0. It will just add one element in the buffer array that will set buffer count equal to i plus 1 and then it will print that it has produced this particular request and then it will increase the count by 1. So now we have one request produced in the buffer queue. So now we call pthread condition signal so we signal this condition variable that items are available now and we unlock the mutex. So what will happen here because this thread was slipping for the items available condition variable so once it gets a signal that items are available this function will return it will acquire the lock again and return and here this will decrease the count by 1 and it will consume the item and print that consume this item. Now after consuming the item it will signal that space is available and it will unlock the mutex. So why do we need this space available condition variable? So here in produce request let's say it is producing request but consumer is not consuming it. So buffer will get full at some point of time so it needs to check this condition that while count is equal to maximum buffer size which means that it cannot produce more request it needs to wait for the space available condition variable again we pass the same mutex to this function as well. So these two condition variables space available and items available result in coordination of these two functions. So produce request will keep producing request and if buffer is full then it will wait for space available and consume request will signal space available after consuming an item and in both these functions we add a random sleeve time so that the next request is produced and consumed after some time. So that is the complete code and let's compile and run this code. So I will first do cd desktop and now gcc producer consumer.c with library pthread. So this will produce the idota executable let's run that executable and if we directly run it we say that we need to mention total items and maximum buffer size so let's write a dot out total items let's say hundred and maximum buffer size may be four so here you see that every item will be produced first and only then it will be consumed so here we see it produced item ever one then it produce item number two then we consume item number two and there is no consume for some item before it is produced so that is the coordination that we get using the condition variables so it will keep producing items and adding it in the buffer and consumer will consume them one by one so that was it for this video thanks and have a nice day