Synchronization 2: Monitors and Condition Variables

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
this video is about monitors and condition variables now monitors provide mutual exclusion and condition variables provide synchronization so these two things are commonly associated but they are separate entities when use in an actual program in fact a monitor is a programming language construct and it is not available in all programming languages however even when the monitor is not available there are usually mechanisms that simulate a monitor fairly well Java is a programming language that has monitors built-in in fact a monitor is associated with every object in every class in Java and you can turn any class into a monitor simply by using Java's synchronized keyword the result looks something like this this code in the top section is actual java code in java you can define a class with a name in this case the name is example monitor and we have methods which are very much like functions and c or other languages that optionally can have this synchronized keyword so if you say public synchronized void example critical section example critical section is the name of the method or function the return type is void and we've specified that this method is synchronized now what that means is that if multiple threads or processes have access to a particular instance of this class and those different threads or processes attempt to execute this example critical section method then only one will ever be able to execute it at a given time you cannot have separate threads or process is executing this synchronized method at the same time if one thread or process attempts to execute this method while another is in the middle of executing it it will block and be forced to wait until the first one finishes now this code down here is not Java code it is pseudocode but it gives you a general idea of what it looks like to use this monitor we have the monitor defined here example monitor it's variable name is M and I've defined integer n to be the number of concurrent processes or threads we want to have running again this method here is the code associated with our thread or process and our main function here does parb again or parallel begin of processes 1 through n so we're launching multiple processes and we once again have an infinite loop in each of the processes and each of the separate processes repeatedly executes this example critical section method associated with this particular instance of the class named M so whenever one of these threads executes that method it will prevent the others from executing it until the first one finishes now this example as I said only provide mutual exclusion to have synchronization we need condition variables now unfortunately although Java does have condition variables they're not implemented as seamlessly and as smoothly as this synchronized method here so this is going to devolve into more pseudocode but the idea behind a condition variable is the following condition variables are another type of data structure and they have two important operations associated with them they have sea weight or condition weight and see notice or condition notify it should also be noted that when you create a condition variable it is either implicitly or explicitly associated with a specific monitor so when we are applying these operations we are doing them with respect to a particular monitor or monitor lock now the C weight command is executed inside of a monitor specifically inside of a synchronized method if we're thinking of this in terms of Java so what C white does is it tells the current thread or process to block itself and give up control of the monitor lock to some other thread or process it's waiting for it it should be noted that as with semaphores each condition variable has a cue associated with it so when you tell a particular condition variable to weight it puts the thread or process in a queue associated with that variable now later some other threader process using the monitor might execute condition notify on that particular condition variable when this happens it causes the next thread or process in that queue to be released making it able to run this level of synchronization is typically needed when you have different types of processes or threads that are doing different jobs so a pure monitor with no condition variables is very useful when all you want is mutual exclusion and we already saw a code example of that but to see how these types of operations are useful we're going to need some slightly more complicated pseudocode so this code is still in the Java style but it is pseudocode these C wait-and-see notify commands don't exist in Java or at least not in this phone armed however we can still get a general idea for how this idea works we've defined a class this one's called monitor with condition variables and we have two global variables defined inside of the class they are of type condition variable their names are c1 and c2 and we have two different synchronized methods method one and Method two now method 1 requires that some condition is met before it can execute so what we have here is a while loop that loops as long as it's not ready to execute so the specifics of this depend on your particular problem and we will see an example in a later video that hopefully makes us more clear but at a general high level this method starts and because this is synchronized no other process or thread can run this method at the same time however just because this process is the only process running this method doesn't mean that it's able to execute it's critical section yet it may need to wait for some condition to be met for example a resource to be produced or some other incoming data to be provided by a different processor thread and so as long as that information or data is not available we have a loop that runs and keeps telling this currently executing thread of process to wait so c1 is one of our condition variables and if this code is not ready to execute then that thread or process gives up the monitor lock and goes and whites in a queue now we can assume that some other codes somewhere else might be executing method 2 and it has a similar while loop and it waits on condition variables c2 so if you do your code correctly then one of these should be able to execute and if one of them executes then they'll do their critical section and then notice that at the end of each of these methods they call C notify so method 2 which has to wait for some condition to be met according to C 2 notifies C 1 when it is finished the idea with this example is that the two separate types of methods the two separate types of processes or threads are communicating in or sharing data or sending information back and forth so when method 2 does a little bit of work it then tells whatever process is using condition variable 1 that it can become unblocked and do a little bit of work as well at which point it notifies C 2 that it can now do its next step of work so these methods are communicating back and forth now this is just the monitor the actual code that would be executed in tandem with this looks like the following we have in another class and once again this is pseudocode monitor with condition variables that's the class we defined here it's name is M so in this example we're only going to have two processes it's running at the same time so we don't need to have a variable for the number of processes running but we do have two separate functions or methods here there's process type 1 in process of type 2 and so the main function does a parallel launch of process type 1 and process type 2 so we have one thread or process that's running this code and a different thread of process running this code and you'll notice that all that happens here is we have an infinite loop that calls method 1 and here we have an infinite loop that calls method 2 and once again the assumption that we have assuming that we're making proper good code and that makes sense is that whatever these conditions are they are such that these methods are going to be able to go back and forth so the thread simply says execute method one over and over again and this one says execute method two over and over again but in practice what's going to happen is method one runs once and then blocks method two is then able to run once and then blocks and then method one is able to run once then block so they go back and forth now other models then this strict back and forth are possible but that's the general idea here now I also said that you can simulate a monitor if the particular programming language you're using does not inherently support monitors so an example of this is the C language C does not support monitors but if you include the right libraries you can gain access to something called a mutex lock so a mutex lock is another data structure and this one has two very straightforward operations they are lock and unlock and all the mutex lock does is provide mutual exclusion if you have a particular mutex lock that is a global variable that is accessible by multiple processes or threads and one of those processes or threads executes the lock command it means that any other process that executes the lock command will become blocked so only one processor thread can ever have control of the mutex at any given time which of course allows for mutual exclusion now once the process is done executing its critical section right doing the code or operation that it has to do then you call unlock and unlock simply gives back control of the mutex lock which in turn unblocks any other processor thread that blocked previously when it attempted to lock these two operations are essentially all that monitor does in fact if we go back to our initial monitor example we are now working in a language so not Java that does not support monitors which means we don't have this synchronized command so if we don't have this synchronized command we somehow have to accomplish mutual exclusion using a mutex lock and if we want to keep the monitor as a separate entity the way we do that is we define a mutex here and then once this method starts we first lock the mutex and then once the critical section code is finished executing we unlock the mutex and this simple change is all that's needed to turn code from a language that doesn't support monitors into code that effectively does the same thing as a monitor in contrast let's say we don't even want to have a separate section of code that represents the monitor and all we care about is a mutual exclusion well in that case we can simply define the mutex here so we're no longer going to have a monitor so now instead of calling the monitor M the mutex is M so we're not going to be using it to launch that method but instead of this method being code in some separate monitor class or monitor programming construct it will simply be another method defined somewhere in this same class or same source code and all we have to do is before we call it we will lock the mutex and after we're finished we will unlock the mutex so monitors are nice and all and they do make coding in a sort of synchronized fashion fairly streamlined but essentially all they're doing is locking a mutex before executing the critical section and then unlocking it afterwards and if you wanted to add condition variables on top of this you could also do that the only difference is that the condition variables would be associated with a particular mutex rather than with a monitor
Info
Channel: Jacob Schrum
Views: 31,162
Rating: 4.941349 out of 5
Keywords: monitor, condition variable, synchronization, mutual exclusion, mutex, lock, unlock, cnotify, csignal, cwait, synchronized, Java
Id: 15Q8PILXkQ0
Channel Id: undefined
Length: 16min 7sec (967 seconds)
Published: Mon Aug 01 2016
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.