All right, everyone, Jerryfs out of town today so Ifll be giving the lecture. And we have two handouts today, two very small handouts actually, the section handout and the solution for tomorrow. So I believe last Friday Jerry started the ice cream store simulation problem. This is a really huge problem. Itfs probably bigger than any single synchronization threading problem that you saw so far in the lectures, and itfs the merger of two or three final exam problems, so itfs pretty involved. So try to go through it as clear as possible but feel to ask me any questions if you want. All right. So let me just start from where we left off last week. So we were talking about the ice cream store and we have four places basically in the ice cream store. We have the cashier which is they are basically to handle the billing issues and we have the customers. We will say we have ten customers and each customer is gonna ask for a random number of cones -- of ice cream cones from one to four. So the least we could have it ten cones and the maximum is 40 cones. And every single customer because he doesnft want to wait for every single cone to be done sequentially, then hefs gonna fight of a clerk or dispatch a clerk for every single ice cream cone that he wants. And so we will have clerks that are making the ice cream cones. We have 10 to 40 of those. But the thing is every single clerk because really giving the ice cream to the customer it has to ask for the managerfs inspection to get an approval for the cone that he made. So the clerks have to get the managerfs approval, and the manger that is only a single manager, only a single cashier, and if the manager disapproves of the cone then the clerk basically has to redo the cone and ask again for the manager inspection. The manager, he doesnft like to have two clerks in his office at one time. So basically we canft have more than one clerk contacting the manager at some point. At the same time -- so this actually starts -- you can start to see the communication that is going between those guys. We definitely can see that we have clerk threads, right? Because every customer -- every single customer would potentially ask for one, two, or three, four clerks. At the same time, we have ten customers that are running in parallel. Itfs not only a single customer at a time. So we have threads here, we have a thread for the cashier, a thread for the manager, a total of probably 52 possible threads, okay. You can see the communication going between the cashier and the customer. You donft expect any communication between the cashier and the clerks or the manager, right? You can see communication between the customers and the clerks depending on how many clerks he fires off, and you can see definitely a communication between the clerk and the manager, right. So you want to start thinking about what are the constructs that you will need in order to maintain synchronizations issues between all of those players in the game, okay. So letfs start thinking, just try to brainstorm about it and then we can look at the code. The thing is the customer comes in and he wants one to four ice cream cones and he will fire clerks. After he gets all his cones he will go to the cashier, right? But he cannot go to the cashier until all the clerks give him back his ice cream cones. So you can start to see, like, this kind of 1 to N communication that we talked about, right. You can see that this guy is gonna request N clerks and he has to wait for the N clerks to get the job done before he can go to the cashier, right. You can also see the communication between the clerk and the manager. So no two clerks can go to the manager at a time which means that there should be this kind of lock around the managerfs office, right. And so only one clerk can access the managerfs office. At the same time the manager will be waiting all the time because he has to wait for all the ice cream clerks to be done for all the customers before he can go home. So the manager will be in kind of a loop just waiting to be requested for an inspection. And once he finishes the inspections he gets back the result to the clerk and he keeps waiting again until all the potentially 40 cones are done and inspected. Make sense? So the clerk will basically have to request from the manager whofs waiting. So therefs the manager waiting for the clerk to request. There is also the clerk waiting for the manager to finish his inspection, right. So we have this kind of binary rendezvous again thing going on in here. You see that? Now there is another constraint on the customers going to the cashier at the end. So the customers are waiting for their cones. And after they get their cones they just go to the cashier in a line and this line has to be maintained on a FIFO order, so a first in, first out, right. And we have to also think about that. How are we gonna insure that the customer that arrives first at the cashier gets really served first and leaves first, right? You will see, again, the kind of binary rendezvous thing between each customer and the cashier because the cashier has to be waiting all the time for a customer to request the service or basically a customer to show up in line. And after a customer shows up in line he will be waiting for a cashier to finish handling his billing and let him go basically, right. So any question on how the setup is for the problem? All right. So letfs talk about the main function. Letfs see what happens in the main. Okay, let me write them in here. All right. So we have the main function. Ifm not gonna write this argument but it basically has to maintain the total number of cones, right? The main function is basically responsible for spawning all the threads that we need. Wefll see that the customers are responsible for spawning the clerkfs threads but other than that everything gets spawned in the main function. So the main function is gonna basically -- you have the total number of cones which is required to spawn the manager because the manager needs to know how many cones there is because he canft leave until hefs done with all the cones, right. So we do the normal stuff, we entered the thread package and we sent up some semaphore that I want to introduce right away. But just bear with me until I get to this point. And then we basically spawned all the customers. So for int I is equal to 0, I is less than 10, int I plus plus. What we want to do is we want to get a random number of cones for every single customer and then spawn the customer and add this number of cones to the total cones that are in here. So I need to initialize this [inaudible]. So we have an int num cones is equal to a function random integer. That gives me back a number of cones between one and four and this function is in the more concurrency handout slide. Ifm not gonna get it. Now once we have the number of cones for a customer then we can just start spawning the customer because all the customer needs to know is how many cones hefs gonna order, right. Make sense? So we got a thread new, debug name, the customer function, and this customerfs gonna take one argument which is the number of cones, right. After doing that we have to add this number of cones to the total of cones because we ill need to pass this total number to the manager eventually, right. So total cones plus equal num cone. Now this is gonna be done for all ten customers and this way we spawn all the ten customers that we have in our simulation. Now we need to model the cashier so we have a thread new, the cashier, and we donft give him any parameters. And we also spawn the manager so we need thread new, the manager, and we pass to the manager the total number of cones, which is single parameter, right. Now wefre done with that, we just run all the threads. After we run all the threads since we did set up the semaphores in here and semaphores, again, remember this is a construct that is appointed to something that is allowed in the heap. So you have to always remember to free your semaphores, okay. So you go and free -- thatfs called a function free semaphores and then you go and end all of the semaphores that wefre gonna introduce, okay. And then you return zero. So this is basically your main function and I donft think, like, in here wefre just spawning threads. You donft see any kind of communication going on. We didnft do anything yet, right? Wefre just starting. So I was kind of thinking about where to start. Typically the sequence, the logical sequence is the customer because thatfs the customer that goes to the store basically to buy ice cream. But I think it might be really confusing to start with the customer. So I will go with the manager because itfs the easier one and then maybe we see the communication between the manager and the clerk, right. And then we try to link it to the customer and the cashier because the customer will also have to interact with the clerk. So letfs go to the manager. The manager and the clerk. I just described a lot of things going on, right. A lot of basically synchronization things that we have to take care of. We need semaphores in here, right. There is like a [inaudible] Ifve just explained. We need to know after the manager inspects a cone whether it succeeded or not, right. So that should be something communicated. It is some sort of communication. So because there is a lot of variables, there are so many variables and there are many threads or accessing all of them, we again do -- we access them globally. So wefll have a global variables, global semaphores. Therefll be a lot of them so in order to make it understandable wefre just gonna group them in structures. So wefll group all the variables that have to do something with a manager and a clerk in one structure and call it inspection and wefll later on do the same thing for the customers and the cashier. We have another structure with all the variables for the synchronization and wefll call it the line, all right. So letfs have our first global -- so we have the struct inspection and, letfs see, the managerfs gonna inspect everything that the clerk shows to him, right? So we have to need basically a Boolean to show us whether the cone passed or not, right. And Ifm gonna be very informal in here. Ifm gonna give you the initializations but all the initializations are basically done in setup semaphores, okay. So wefre not gonna go through this function. But this pass is gonna be false. Now what else do we need? The manager has to keep waiting until itfs requested, right, for inspection? And also the clerk has to wait until it knows that the manager finished its inspection, right? So we need some kind of semaphore for rendezvous the semaphore is gonna be -- letfs call it requested. And so this is gonna be signaled by the clerk to the manager that it requests an inspection, right. Make sense? All right. So this semaphore is gonna be initialized to zero, okay. So basically the manager what itfs gonna do is basically gonna wait on the semaphore which means itfs gonna block, okay. Until a clerk comes and sends the semaphore so it basically wakes up the manager. Make sense? All right. So we have the semaphore requested. We have the semaphore finished and we also understand that once the manager -- once the clerk requests inspection it will wait on this finished semaphore which means itfs gonna block until the manager finishes the inspection and then signal the semaphore and then it wakes up, okay. So what else do we need in here? What else do you think wefre missing? Okay, letfs start working and see what we miss, okay. Letfs start working on the function and see what we need. So wefll have the function manager. So thatfs void manager, the manager takes an N which is the total number of cones. So letfs call it total cones needed. And here is what the manager does. Ifll have two variables, one of them is required, the other one is not. The first one is total, letfs call it num approved. So this is num approved which is initialized to zero and another one which is num inspected also initialized to zero. So what we need to do is the following. While the number approved is less than the total number needed then you basically can go home, you have to keep waiting and keep inspecting, right? So while this is the case what you want to do is the following. You want to wait until a clerk requests your service, right? Okay, so you want to wait on inspection, let me finish this here. So you want to wait on inspection, not requested, right? Once you get a request -- yes, go ahead. [Student:]Which are not needed as [inaudible]? [Inaudible] not needed? Those are not needed? [Student:]Yes. So did you see when that spawned the manager thread? We passed the total cones and the total cones were the total number that a customerfs wanted. So thatfs the total number that basically the manager needs to inspect. Thatfs total number of cones, yeah, that all the customers will buy, you see. [Student:]Oh, okay. So thatfs the total number of cones. Yeah, Ifm just calling -- I mean, Ifm just changing the name of the parameter but thatfs fine, okay. Any other questions? All right. So you want to basically wait on the request for the inspection, okay. And then once you get a request for an inspection you basically want to inspect the cone, right? Okay. So what you do is you have your -- once this is done you basically are inspecting a cone so num inspected will go up and you have to check if youfre gonna approve this cone or not. So we simulate. This is modeling, right? So we have a random function that says sometimes, yeah, we do approve, sometimes not, okay. So we will say inspection not passed which is the Boolean in here is equal to some random chance. It returns one of the two things, zero or one. And again, Ifm not writing this function but you understand what itfs doing, okay. So again remember Ifm assigning this to dot passed because this is the Boolean that Ifm using to communicate between the manager and the clerk, okay. Now if you really passed -- if inspect got passed then what you want to do is basically increase the number of approved. Make sense? So num approved plus plus. Now we finished your inspection, okay. The only thing he has to do but what you know is that the clerk is potentially waiting on your finished. So you want to signal finished. Any questions? Yeah, go ahead. [Student:]Yeah. Are we using global variables mean or -- Yes, we are. [Student:]Okay. So this structure is basically a new one. [Student:]Okay. Okay? And everything inside is basically initializing this function [inaudible] semaphore, okay. And Ifm giving you the initialization. So all these are gonna be semaphore new, okay. All right. So after we do that whatfs left off is just a signal, the inspection not finished because you know that the clerk is gonna be waiting on the semaphore, okay. And thatfs your manager and thatfs the easies function of all. Now letfs go to the clerk. Now any question on that before I move on? All right, so the clerk. The clerk -- wefll pick some parameter. Ifll worry about it later. Because this parameterfs gonna be rated to the customer and I didnft write the customer function yet. So, letfs see, what the clerk needs to do. It needs to make one cone and have the manager inspect it, right. It needs to repeat this cone until it passes, okay. And once it passes it just hands the cone to the customer. All right. So, letfs see, the clerk basically starts with a cone that doesnft pass. So Boolean passed is equal to false. And why you didnft pass you basically need to make a cone, right. And then request the manager to inspect it, okay. So letfs see, we can potentially have up to 40 clerks requesting the manager to inspect their cones, right? Okay? Does this give you any hint about what wefre missing here? [Student:]A binary lock. Exactly. So we need the binary lock. We basically need to lock the managerfs office, right, so that we can insure at any point in time only one clerk can get in this office, okay. So here we need another semaphore which I will call lock, and this semaphore is gonna be initialized to one, right. Why is it initialized to one? Why not zero? [Student:]So it can get in the office. Exactly, so that at least one clerk can get in. If you initialize it to zero then nobodyfs ever gonna get in the office, right. So you want one clerk at least to get in. And you want only one clerk to get in. You cannot have it zero. Zero is a deadlock, right, because nobodyfs gonna ever be able to get in. You cannot have it two because two means two clerks can potentially be in at the same time, okay. All right. So the first thing that you want to do basically is to acquire this lock, right? So you want a semaphore wait on inspection dot lock, and again, there are two scenarios. First of all is that lock is still one because nobody did the wait before in which case youfll be able to proceed. The other scenario is that this is zero in which case you just block on it and wait until it is signaled, okay. All right, so you wait on this lock. After you wait on this lock you basically need to request the service of your manager, right. Okay? So what you want to do is semaphore signal, inspection requested. Am I going too fast? Is it clear? Okay, so we signaled the request and after the -- yeah? [Student:]Some [inaudible] to one? Excuse me? [Student:]Would it say requested to one? It would, yeah. So request is originally zero, right? The manager, which I just wrote in here, it doesnft wait on requested which means it blocks. So the way our semaphores in the library that you are provided the semaphore doesnft go to a negative value, okay. So it always maintains a zero or a positive value. So if itfs zero and you try to decrement it, it doesnft not allow you and it blocks. So you keep waiting there blocked until somebody makes it positive. So you can decrement it to zero, okay. And this is how the blocking works, right. So what happens here is that the manager would be blocked if he starts before the clerk because what will happen is the manager will try to decrement the zero semaphore but it will block and then it will wait until some clerk comes and does signal the inspection request which will make it positive so the other one will be able to proceed and the command does. Do you see how this works? Okay? All right. So you did signal request. Now after signal request the manager will get the request, right, and will start working on this. What you need to do at this point is wait until he finishes. Make sense? So you just -- [Student:]Itfs really [inaudible] is like if you have inspection request of him and if you lock up a manager why is it he requested? Thatfs a good question. Let me finish it and then Ifll answer this question, okay. Ifll just go on because, like, I want you to see the whole picture after we finish it. So we will basically wait until the inspection is done. So after the inspection is finished and once inspection is finished you basically want to know the result of the inspection, right? You want to know if your cone passed or failed. Now how do you know that? Which field tells you? [Student:]Inspection dot passed. Inspection dot passed, right? Now you want to read into passed whatever the manager passed in inspection dot passed, okay. So you want to set passed equals to inspection dot passed. Now you know that if passed now is two then youfre not gonna do this anymore and youfre gonna move on, okay. Youfre done with this point but remember that you were locking the managerfs office, right. You no longer need to lock the managerfs office. Make sense? So you want to signal -- so you waited on the lock in here. You want to say that it semaphore signal inspection dot lock. There is something missing here. I will finish it when we talk about the customer. Now back to your question. So the question is the following, why do we need to have lock and requested. Why do we need those two? If lock already grants us access to the manager, right? So think about what would happen if you donft have them, okay. So letfs say you donft have the lock. Itfs obvious that you need it, right? Because you will have two clerks to go to the manager at the same time, right? Now, think about if you donft have requested. Then what will the manager do? Not at all, like, basically the manager will not wait for any inspection, right? It will go on and proceed with passed, give it a random value and go on and keep going in the loop, right? Now which clerk will be checking its own inspection dot pass you donft know, right? This lock is crucial and itfs crucial that you maintain this -- this is maintaining this kind of critical section in here, right? This lock is extremely crucial because basically you donft want to release this lock until you read the value of inspection dot pass. Note that this value is shared among all the clerks and the manager, right? Itfs a single value. And because we allow only a single clerk to be with the manager at the time then we can safely assume that the value in here will be up by this clerk that is with the manager. But you have to insure that no one else can be in that portion, okay. You have to insure. So this lock insures basically that you have this critical section in here. It insures that you can read this passed before you release the lock and before any other clerk can be with the manager. Because potentially letfs think about it differently. What happens if you switch those two lines? What happens if we first signal the lock, basically release the lock and then check the value of whatfs in inspection? Whatfs in passed? Ifm sorry. [Student:][Inaudible] inspection dot passed. Potentially, youfre not sure, potentially. What happens is if we had those two lines kind of flipped what would happen is probably you could have the inspection dot lock signaled, which means that the lock of the officer of the manager is no longer locked and any other clerk could get in. Now if youfre Fred, which is this clerk, Fred, gets pulled out of the processor at this point it is very possible that some other clerk could get into the managers office, show him his cone, get his passed value of right original pass value before this guy gets back the processor. Do you understand that? All right? Now another thing, letfs see, what would happen if the manager was the one to signal an inspection lock? Like he would say, gOh, here, letfs give the control to the manager.h And the manager has his office lock and he could just unlock it. What is the problem with basically moving this line from here to the manager? You see any problem with that? [Student:]Isnft it the same person. Itfs exactly the same thing. Itfs basically the manager is gonna unlock the inspection lock. So hefs gonna unlock his office and we donft know if this guy actually did execute this line or not, right? So, again, the lock would be opened, the door would be opened, any other clerk could get in, could override the passed value before this guy gets to here. Make sense? Yes? [Student:]What is -- so the manager waits on inspection dot requested. What if the manager just waited on the door being unlocked? Because it seems like once you unlock the door you make your request at the same time. Itfs like the same thing. So what you want to do is the following, you want to have the manager waits on the lock. [Student:]Yeah. And you also have the clerk wait on the lock. [Student:]The -- You see the problem with that? [Student:]-- clerk waits on finished. The clerk doesnft even -- What would happen is you have a manager waiting on lock. You have two clerks signaling lock and getting in. You see the problem? The thing is binary rendezvous itfs always you need those two things because one is waiting for the other to finish something and the other is waiting also. Itfs exactly the same idea of the Buffered Writer and Reader which is also generally called the Consumer [inaudible] Problem. So you have some consumer that consumes some [inaudible] of something, another consumer that consumes the same thing. Now this is exactly the Buffered Reader and Writer. And what happens is somebodyfs waiting for the other to produce and the other is waiting for him to consume, okay, because there is some shared source in the middle. So you always need those two things to maintain basically the two -- you see, the two basic synchronization of the two agents. Whoever is producing waits for the other to consume and the other way around. Make sense? Any other questions? All right, so wefre basically done with the manager and part of the clerk. Wefll have to revisit the clerk when we talk about the customer. But before we move to the customer then now wefre gonna be talking about the relation between those two guys. And wefll also talk about this guy, the relation between those two. Letfs first start with the easy part. Letfs see where itfs put here. So we have a void customer and the customer takes the random number of cones that he needs to order, right? So he takes an int num cones and letfs see what he does. The customer gets in the store he is browsing. This is just wasting processing time. Nothing, right? Hefs gonna spawn N num cones clerks to do every single cone for him, right? So he will basically need to get num cones clerks, like if this is three clerks to work on his cones and wait until theyfre done. Okay, before he can move on to the cashier. Make sense? So this means that we will need to have some semaphore and why we need to have it because we know that we need to wait for all the clerks, okay? So we need the semaphore. Letfs call it clerks done. And this one we initialized to zero again, okay. And then for int I is equal to 0, I is less than num cones, int I plus plus, what you want to do is basically fire each clerk for your cone. So you do a thread new right at the end, and then you fire the clerk. Thatfs a debug name. The function is the clerk, right? And now we need to pass to the clerk the semaphore because you will wait on the semaphore for all the clerks and you want every clerk when he finishes the cone to signal this back to you which is equivalent to handing -- to giving you basically the cone. Make sense? So you want to thread new a clerk passed to it one parameter which is basically the clerkfs done semaphore. Now this takes us back to here, okay. So this clerk takes a semaphore, letfs call it sema to signal. And once itfs done making the cone, inspecting it, approving it and itfs all done then you basically want to semaphore signal the sema to signal. Make sense? Now thatfs for the clerk. Now wefre done with the clerk. This guy just spawned num cones clerks, right? He needs to wait for all of them. So he saw last lecture how we do that. You just have another for loop for int I 0, I less than num cones, int I plus plus. You want a semaphore wait on clerks done. Now we know that this guy will never get past this point until all the clerks are done with all his cones, right? At what point you just could basically go and free this semaphore because you wonft use it anymore, okay. So you could just go here and is it free semaphore or semaphore free? Semaphore free. Okay. You can double check that. Semaphore free, clerkfs done. And then you walk to the cashier. Starting at this point you will see how the synchronization works between a customer and the cashier and I think this is the most tricky and the hardest part of the whole thing. Yes? [Student:][Inaudible] the semaphore wait on the for loop [inaudible]? Thatfs a very good question. So the question is the following, why donft we include the semaphore wait call and the for loop in here to just have a single for loop that has basically the thread new and the semaphore wait. Anybody has an idea? Yeah, go ahead. [Student:]Because wefll -- the clerks will only be spotting once at a time? Yeah, any other ideas? Anybody [inaudible] that? So what happens if you do that is the following, you get a clerk and you wait on done, right? Now you did actually initialize clerkfs done to zero, right, in semaphore new. Once you wait on this you basically block, okay. So you will be blocked in this line. You want be able to go any further in the for loop. You understand what Ifm saying? Until this guy who you just spawned does a semaphore signal on done so you can get to the next one. So basically youfd be doing it one by one, okay? Yes? [Student:]Can you make this [inaudible]? Right. So the question is the following, can we make the semaphore and a shared integer value variable or a [inaudible] to variable. And so this takes us back to the problem of [inaudible] end use, okay. So the main reason why we using semaphores or locks or those basically concurrency constructs is that we need to insure atomicity. And by atomicity, we mean that we want to decrement the value or increment it and check its value in one operation or in several operations that are guaranteed to be done atomically. So if you have an integer, the thing is you will increment or decrement it and then you will check its value and between the two you could get of the processor, okay. Yes? [Student:]Yeah, how does it know what threads it owns? Like, if -- say youfve done the for loop and you went out of bounds by one, so you did like num cones plus 1. How does it know what threads to wait on like -- How does it know what threads? [Student:]Well, like you say semaphore wait, clerkfs done. Yes. [Student:]And youfre waiting on the semaphore but, I mean, youfve created that semaphore four times already for the four different threads. Thatfs correct. You donft really care to know which thread is gonna signal it. You donft care to know or at least in the -- in terms of the function itself you donft care to know which one is gonna signal you as long as you know that somebodyfs gonna signal you. [Student:]So probably one of the threads youfre waiting for on semaphore wait could be some other customerfs thread that was a clerkfs done? One of the ones in -- no. Know that I am actually having this as a local semaphore in here. [Student:]Okay. So if any other customer has also another local clerkfs done thatfs a different issue. Itfs a different semaphore basically. All right? Any other questions? All right, so you recently walked to cashier and from that point on wefll be dealing with the cashier and the customers. Now, I was just saying that this is a tricky spot and this is the tricky spot because of the constraint that we impose which is to handle all of them in a FIFO order. Basically whoever goes in line has to be first, okay. And now you have to think about what goes in the second struct. So, again, wefre having a struct in here basically because it makes sense that we group all the semaphores that have to do with the inspection and the clerks and the manager together, right? But there was nothing that would have -- kind of prevented us from having them all independent, just having grouped the semaphores up there. Wefre just grouping them just so it makes sense to you, okay. So letfs look at the other struct. So we have another struct, we call it line. And this struct has all the semaphores that would handle the communication between the customer and the cashier. Now the customer has to go to the cashier, it has to stand in line and it has to wait for its turn. So basically it has to take a number, right, which is the next place available in the line, okay? So thatfs have in here something called the number. And this number -- this struct again with all the fees that Ifm gonna put in here is supposed to be initialized in semaphore and setup semaphores in here, okay, in the very beginning. I just kept it to the end so that it makes sense with what wefre talking about. So the number would be initialized in the beginning to zero because this is the first place in the line, right? Nobodyfs there yet, okay? Now the cashier is gonna be waiting until somebody shows up in line, right? And when somebody shows up in line this means that a cashier is requested, okay. So we have a semaphore that the cashier is gonna wait on saying, gIfm waiting until Ifm requested.h Okay? Until somebody basically shows in line. So we have a semaphore requested and this is going to be initialized to zero. We also have another semaphore; this is a little tricky, now each customer with the cashier they have some kind of synchronization going on, right? Every customer has to go and say, gOkay, signal me when you are done with my bill. And it has to be me because I am waiting in the queue in this specific position.h Right? So there should be some -- itfs not really that we are the customers and we are waiting for you, cashier, to signal somebody of us. Itfs not really somebody, itfs not any one of us and somebody will leave. Wefre not caring about all the customers leaving in the end; we are really caring about every single one of them leaving in his turn. Right? And this should give you an idea about having this kind of struct that would have a semaphore that is a rendezvous semaphore between every single customer and the cashier but this semaphore has to be for every single customer because it has to maintain the order of every single customer. Does that make sense? So in here we will have a semaphore, letfs call it customers, and those are the customers that basically requested the cashierfs service but are waiting to be serviced, okay? So this is gonna be an array of ten semaphores, one for every single customer in turn, okay. So you come, you pick a number, you know youfre number three, then you are gonna wait on the semaphore of three. And the cashier, once he gets to your turn hefs gonna signal customer of three so thatfs you -- itfs your turn to leave. Make sense? [Student:]Why ten customers? Because we just assume ten customers. You could have a single number, yeah. [Student:]So one point that the customer in the front of the line makes their request and that -- and then he leaves and then the next person makes their request and he leaves so that the line of clerk only deals with the one -- only one customer. This is basically what wefre doing. What youfre trying to say is how can we -- so let me ask you the question, okay? How can you insure that the customer -- the first one in the line is the one that came in order? Because basically remember that you are not keeping track of the state. There are customers that finish and they get all their cones and they go to the cashier, right? You donft remember who came first. You donft remember the order. You donft remember which one picked the number, right? If you say the one in the beginning of the line thatfs what wefre doing basically, wefre keeping track of who is at the beginning of the line. Wefre gonna say if itfs the one in place number zero and move on to one which is basically the beginning of the line. If you say that they shift, right? But if you donft do that then you donft know because you have like threads that finished at random times and you have no clue whatsoever which finished first. Make sense? Yes? [Student:]If you had multiple semaphore waits and you do just one signal will all of them wake up or just one wake up? Are you talking about those arrays that Ifm having here? When you do a wake up you wake up the specific semaphore. You donft wake up any one of them. [Student:]But generally do you just [inaudible] waiting on a semaphore? At least if you do wake up -- [Student:]At the signal. -- what happens typically -- this is an OS issue, but typically what happens is when you have somebody waiting on a semaphore itfs put on a block list, right? And so you have all those threads that will be put on the block list and it depends on the scheduling issue. So it depends on whether you pick a shortest job first or you pick a priority scaling, whatever. But whoever gets to be scheduled once he finds that his semaphore was signaled then he will be able to proceed, okay? All right. So now we have the customers and wefre still missing one thing which is very similar to the one thing that we missed before. Can anybody see it this time? [Student:]Having a lock on the cashier? Having a lock on what? [Student:]On the cashier. Having a lock on the cashier. Why do we need the lock? [Student:]Because they can only deal with one customer at once. But actually you can see that the cashier is maintaining this thing because the cashier is the one thatfs gonna be waiting for requests and hefs gonna be spawning basically -- hefs gonna be signaling one of those. Anybody sees any other problem? [Student:]Yes, a lock for the number. Exactly. We need a lock for the number. Basically you can think about this. Two guys go, they check what is the number. The number is zero. The other one also -- and the first one gets out of the processor. The other one gets the -- gets to be scheduled, checks the number, itfs still zero and they both increment the number; they both get the number one, right? So this is why, again, we need the lock on this number to make sure that this is the shared resource, this is where we have race conditions and this is what we want to secure, okay? So let me have a semaphore lock and to what is this semaphore gonna be initialized? [Student:]One [inaudible]? Yes, itfs gonna be initialized to one and I think I will need to write the last few lines very quickly because wefre running out of time. All right, so let me write the cashier first and then we go to this guy. Herefs what the cashierfs doing, very easy. This is the cashier. Itfs not taking anything. And what the cashierfs doing is basically for the number of customers what hefs doing is hefs waiting to be requested. Once hefs requested he handles the bill, checks out the customer and then signals the semaphore, okay. So you have a for loop for int I is equal to 0, I less than 10 int I plus, plus. What you want to do is semaphore wait on line. So this is line. So you wait on line until requested. Once you are requested then you know that you are basically servicing the first customer in line. So you check out some function. Check out customer I and then you signal customer I because you know hefs the first one in the queue -- in the line. So you semaphore signal line dot customer of I, all right. And thatfs your cashier. Now letfs get back to the customer. So you walk to the cashier, okay? What you want to do is you want to signal to the cashier that you request a service and wait for the cashier to handle your bill, right? So you want to semaphore signal line dot requested and then you want to semaphore wait. Oh, I forgot something very important. I donft know my number, right? I didnft even get a number, okay? So before you request you want to get a number but before you get a number you have to lock, right, because you donft want anybody else to be getting a number at the same time. So we want to semaphore wait on line but lock. You want to get the number so we simply an int, letfs call it to replace, this is equal to line. -- what did I call it? Number plus plus so that next time is the next place on the line, okay? And then you want to signal definitely this lock because you are done using the number. And after you signal this lock, maybe right here, you want to signal to the cashier that you are requesting his service. So you signal line dot requested and then you want to wait until he handles your bill. So basically wait on line dot customers of your place, okay? And this is your customer. I donft think Ifm missing anything. Does it make sense? Are you guys confused? This is hard. This is not an easy -- itfs not that itfs -- itfs not as complicated, itfs just that itfs just a lot of problems going on, a lot of synchronization issues going on. So I would definitely suggest that you guys go and do this again, okay? You have to think about it. You have to think about the interactions between all of the players. You have to think why you need those semaphores and how youfre gonna use them. Ifm gonna see you again tomorrow in this section. Wefre gonna go over another example for the studying and itfs gonna be related to your assignments -- to your project, okay? Okay, have a good day.