[Music] in this lecture we'll be starting a new chapter which is process synchronization so we will try to understand what is process synchronization why we need process synchronization and how it is a very useful and important part of operating systems so by process synchronization we mean that we need to have some kind of synchronization between the processes and why do we need that we'll find out as we move ahead so first of all we need to understand the term cooperating processes so it says here a cooperating process is one that can affect or be affected by other processes executing in the system so we know that there are multiple processes executing in a system so if the execution of one process can affect other processes and vice versa then we say that they are cooperating processes so these cooperating processes can either directly shared a logical address space which is both code and data or be allowed to share data only through files or messages so when we are having cooperating processes they will be sharing a region of data there will be a shared region of data which these cooperating processes can access and manipulate so they can either share a logical address space so by logical address space we mean that they are sharing both the code and the data or they will be allowed only to share data through files or messages so these are the two ways how sharing can take place between cooperating processes now what is the problem here so the main problem that we have here is concurrent access to shared data may result in data inconsistency so we know that corporating processes will be sharing a region of data so they will be able to access that shared region and will be able to access and manipulate that shared data now if multiple processors are concurrently trying to manipulate data then that will lead to data inconsistency so that is the main problem that we have here if two or more processors are trying to manipulate the same data at the same time then that will definitely lead to data inconsistency so that is why we need process synchronization so in this chapter we discuss various mechanisms to ensure the orderly execution of cooperating processes that share a logical address space so that data consistency is maintained so this is what we are mainly going to discuss in this chapter we are going to discuss various mechanisms that will ensure the orderly execution of cooperating processes that share the logical address space so when they are sharing a logical address space means they are sharing both the code and the data so for these kind of processes that are sharing both code and data when they concurrently try to access shared data it is going to result in data inconsistency so we need to discuss about the various mechanisms that we have that will ensure that the cooperating processes will share the logical address space in an orderly fashion such that the data inconsistency can be avoided and hence we will have consistency maintained in our data so this is the main thing in this chapter and the main objective that we are going to follow so keep this in mind that this is why we need process synchronization now let's take some examples to understand in a clearer way why this process synchronization is important so the best example that we can take is the concept of shared memory systems so in one of our previous lectures we have already studied about shared memory systems so in shared memory systems we saw how multiple processes share a region of memory and the processors can write into their region of shared memory and also read from that region of shared memory so there when we discussed about this shared memory systems we came across a problem known as a producer consumer problem so if we just recall that we can see that in producer consumer problem what was happening was a producer process produces information that is consumed by a consumer process a producer process is the one that is producing information and the consumer process is the one that is consuming the information so we took some examples like a compiler may produce assembly code which is consumed by an assembler and also we can take another example like a web server is producing web pages and then the client through the browser is consuming the web pages so one solution that we found for this producer consumer problem was the use of shared memory so we have seen how memory was shared between processes and how multiple processes could write to that region of shared memory and read from the region of shared memory and also we see that there was something called buffer that we had so buffer is a place where the producer will produce the information and keep it and it is also the place from which the consumer will consume the information so the buffer will reside in a region of shared memory that is shared by the producer and the consumer processes so we also saw that the producer can produce one item while the consumer is consuming another item and also we must make sure that the producer and consumer must be synchronized so that the consumer does not try to consume an item that has not yet been produced so these are the things that we saw and when we discussed about the buffer we also discussed about two kind of buffers which is the bounded buffer and the unbounded buffer so unbounded buffer is a buffer that practically places no limit on the size of the buffer and bounded buffer is the one that assumes a fixed buffer size so in bounded buffer the consumer must wait if the buffer is empty and the producer must also wait if the buffer is full because we are having a particular fixed size in this bounded buffer but an unbounded buffer there is no practical size so those were the kind of buffers so this is just a recapitulation of some of the things that we have studied in shared memory systems because we are going to use this for explaining process synchronization so now let's say for example we are going to use this bounded buffer and we are going to modify it a little bit so what is the modification that we are going to make so we know that in a bounded buffer we need to keep track of the items that are present in the buffer because we need to know when the buffer is full and we also need to know when the buffer is empty so let's say that we are going to use a variable that is going to count the number of items that are present in a buffer so that means when something is added to the buffer by the producer the variable will be increased and when something is consumed from the buffer by the consumer then the variable will be decreased so let's say that the name of the variable is counter so counter is the name of the variable which is going to keep track of the number of items present in the buffer so for the beginning we initialize the counter variable to zero that means the first value is zero so now what we will do is the counter is incremented every time we add a new item to the buffer and the counter is decremented every time we remove one item from the buffer so whenever a new item is added to the buffer by the producer then we are going to increment the value of this counter by one so we are going to have a counter plus plus operation that means increment the counter by one so counter plus plus is equal to saying counter equal to counter plus one so we'll be incrementing it by one every time the producer adds an item to the buffer and similarly the counter will be decremented every time we remove one item from the buffer that is every time an item is consumed by the consumer from the buffer we will decrement the counter by one so we are going to have a counter minus minus operation so counter minus minus means counter equals to counter minus 1 we are decrementing the value of the counter by 1. so let's take an example based on this so let's say for example suppose that the value of the variable counter is currently 5 so we have a buffer where the counter variable is currently 5 so 5 is the value and the producer and consumer processes execute the statements counter plus plus and counter minus minus concurrently so at some point of time when the counter's value was five the producer process and the consumer process both respectively tries to execute the statements counter plus plus and counter minus minus concurrently that means the producer tries to produce an item and hence it wants to increase the counter by counter plus plus and then the consumer also at the same time consumes an item and wants to decrease the counter value by counter minus minus so what will happen in this kind of a scenario so following the execution of these two statements the value of the variable counter may be four five or six so if these two statements are executed then following the way in which these executions took place the value of the counter variable could be 4 5 or 6 depending upon how it was executed so let's say that the counter variable was 5 and then counter minus minus occurred first then what will happen five will be decremented by one then it could be four or let's say that when counter's value was five counter plus plus happened and then what will happen the counters value will be incremented by one so five plus one six so among these three values four five and six which should be the right value of the counter so actually the only correct result though is counter equal to five which is generated correctly if the producer and consumer execute separately so the actual value or the actual result should be 5 and why is that that is because the initial value of the counter was 5 and if one item was produced by the producer then it will become 6 and then if one item was consumed by the consumer then it will become six minus one five back to five so it's just like let's say that you are having five apples with you and then your friend gave you one more apple so you got one more apple it became six and let's say that you ate that apple so how many do you have now you still have five so that is the same thing that should happen here the original number was five and the producer produced one item but the consumer also consumed one item so the final value of the counter should be 5 so 5 is the only correct result that should be there but will we have the correct result of 5 if the producer and the consumer try to concurrently execute counter plus plus and counter minus minus let's try to find it out so before we go into that we need to understand how does counter plus plus and counter minus minus work in a machine level so when we are writing a program we may be writing the code saying counter plus plus or counter minus minus but we need to have an understanding of basically how does it happen at the machine level then we'll be able to understand how these values come so this is how counter plus plus will be implemented in the machine language so counter plus plus may be implemented in a machine language on a typical machine as follows so when we are writing programs we are writing in some high level programming language but everything finally it breaks down to the machine language and that is how it will be executed at the low level so let's see how it is done so when we implement the counter plus plus operation this is what happens so first of all we are making use of registers here so at the machine level we are going to make use of registers so here let's say that we have a register called register one which is a local cpu register and what will first happen is the value of the counter will be stored to the register one so what is the value of the counter it is 5 so the value 5 which is in the counter will be stored to register 1. so register 1 now has the value 5 and mind it counter is still 5 register 1 is also 5. now what happens is the register one's value is incremented by one so register one equal to register one plus one so at this point of time what happens the registers value the value that was in the register which was five is incremented by 1 which is 5 plus 1 equal to 6. so the value 6 is now stored to register 1. so at this point of time remember register 1 holds the value 6 and counter is still 5. then at the last step what happens is counter equal to register 1 that means whatever value is in register 1 store it to the variable counter so what is the value in register 1 it was 6 we just saw it so the value 6 will be now stored to the counter variable so the counter now becomes 6 so that is how counter plus plus works using the registers first the value is stored to the register from the counter then the register is incremented by 1 and then the value in the register is stored back to the counter so that is how counter plus plus works on the machine level so similarly counter minus minus may be implemented in machine language on a typical machine as follows so in a similar way it will be implemented so let's say we have register called register 2 so the value of counter which was 5 will be stored to register 2 then register 2's value will be decremented by 1 register 2 minus 1 so 5 minus 1 equal to 4 so the value 4 will be now stored to register 2. then what happens counter equal to register 2 that means whatever value we seen registered to store it back to the counter so the value 4 which is the value of register 2 is stored back to the counter so counter becomes 4 so that is how counter minus minus is implemented in a machine level so now since we have a basic understanding of how counter plus plus and counter minus minus are implemented in machine level now we are in a position to understand this example so here we said that the counter's current value is 5 then the producer and consumer both tries to execute counter plus plus and counter minus minus at the same time so what will happen the values can be either 4 5 or 6 but the only correct value should be 5 so let's see what the value will be so here is a table that depicts how this process takes place so at time t 0 the producer is trying to do its execution so what is a producer trying to do the producer wants to produce an item to the buffer and hence it wants to increment the counter by one it wants to do the counter plus plus operation so what is the first operation that should take place in the counter plus plus at the machine level first of all in register one the counter's value should be stored so first of all at time zero the producer executes and it sets the value of register one equal to the value of the counter so the value of register 1 is equal to 5 because we are assuming that the present value of counter is 5. all right now at time t1 the producer will do its next execution now what is the next execution in the counter plus plus operation the register's value has to be incremented by one so register one is equal to register one plus one so the value and register one is incremented by one so what was the value it was five it is incremented by one so it becomes six now let's say that at time t2 the consumer is consuming something from the buffer and hence it also wants to decrement the value of the counter by one so what happens the consumer is now executing and then it wants to do counter minus minus so what is the first step register 2 equal to counter so it is going to say register 2 is equal to counter the value and counter should be stored to register 2. so mind you till here we have not modified the value of counter the value of counter still is 5. only the registers have been modified so when we say register to equal to counter what will happen register 2's value will be replaced by the value of the counter and what is the value of the counter it is still 5. so register 2 is equal to 5 so what is the next step in counter minus minus register 2 equal to register 2 minus 1 so the consumer still does its execution and what is it register 2 equal to register 2 minus 1 so what is the value and registered to 5 so 5 minus 1 4 so that is the thing that happens in register 2. now let us observe and see that till this point only the registers have been modified by the producer and the consumer but the value of counter has still not been modified yet so what happened here both the producer and consumer are concurrently trying to modify the value of the counter so that is why they did all these steps till now now what happens if the producer is the first one to get hold of the counter then it will do its execution and do this final step which is counter equal to register one so if counted equal to register one happens what will be the value of counter what is register 1 register 1's final value is 6 so the counter will be stored with the value 6 so counter equal to 6 will be the final value of the counter but let's say that if the consumer was the first one to get hold of the counter then what will happen the consumer will execute this last statement counted equal to register 2. so if counter equal to register 2 occurs then what will happen what was the value of register 2 it is 4 so the counter's value will be stored as four so this is what happens they are trying to concurrently execute and when they're trying to concurrently execute whoever is first getting hold of that counter will assign the value to the counter so if producer is the first one to get hold of the counter then the counter value becomes six and if the consumer gets hold of the counter first then it is going to store the value of counter as four so here we see that we would arrive at this incorrect state because we allowed both processes to manipulate the variable counter concurrently so we already saw and we already explained that the correct value should actually be 5. so if the present value of counter is 5 and if one value is added and if one value is reduced that means if the producer put something there and if the consumer consumes something from there then the final value should still be 5 but here we see that it is going to be either 6 or 4 which are both wrong so we would arrive this incorrect state and why did we arrive at this incorrect state because we allowed the counter to be manipulated by the producer and the consumer concurrently if we had allowed one of them to complete and then let the next one to do its work then we would have not arrived in this wrong situation so a situation like this where several processes can access and manipulate the same data concurrently and the outcome of the execution depends on the particular order in which the access takes place is called a race condition so here we saw that in this scenario when the producer first gets hold of the counter it was giving it the value 6 and if the consumer was the first one to get then it was giving it the value 4. so there is a raise between the producer and the consumer whoever first gets hold of the counter is the one who is going to give the value to it so this kind of a situation is called a race condition so several processors are accessing and manipulating the same data and then the final data will depend upon the order in which the access took place so here we saw that if producer is the first one this 6 is going to be the value if consumer is the first one then 4 is going to be the value of the counter so this kind of a situation is called a race condition so this is an important term that you should remember so we see here that we have arrived at the wrong result because we have allowed two processes to concurrently access the same data and these processes were not synchronized between each other so clearly we want the resulting changes not to interfere with one another and hence we need process synchronization so we don't want this kind of a situation to happen we don't want two processes or two or more processes trying to access and manipulate the same data and then causing some kind of inconsistency of the data as we saw just now we want the data to be consistent so we need the process to be synchronized with each other and we don't want the resulting changes to interfere with one another so this is why we need process synchronization so this is one strong example that we can see in operating system and we see that we need to definitely avoid this kind of situations so we are going to study of various techniques that are there in order to avoid this kind of situations so we will be seeing such kind of problems related to process synchronization and we will be seeing what are the various methods that have been formulated in order to avoid this kind of problems and as a whole what we want is we want to maintain data consistency so that is the main objective of process synchronization so i hope this introduction to process synchronization was clear to you and i hope you got an idea of what we are trying to study and why we need to study this so i hope this was clear to you thank you for watching and see you in the next one [Music] you