 Welcome back everyone. My name is Brian and we're going to continue our journey into Python with multi-processes. We're going to look at starting and stopping. In short, we're looking at the full process life cycle. Here's an example of what we're going to be doing. We're going to start the application. We're going to start a worker and then we're going to finish and get the end result back from that worker process. When I say end result, we're talking about the exit code from that process. Let's take a look. First things first, before we can do any work, we have to do our import. We're going to import logging. We're also going to import multiprocessing. Then we're going to say from multiprocessing.context. When we talk about context, we're talking about the context of execution. Specifically, we're talking about a process. When you think about context of execution, really you're talking about scope. Every process has its own scope. It's actually pretty cool how that works. We're going to go ahead and import time so that we can stop time when we need to to make it look like the program is actually doing a lot of number crunching. We are going to do more complex examples in the future, but we just want to simulate work at this point. Let's go ahead and define the function that our worker processes are going to use. In this example, we're only going to use one process, but it can be used over and over again for a number of processes. I'm going to say def. Let's go ahead and call this work. Let's say msg for message and max. Really, we're just going to count something out and spit out a message. Let's go ahead and get the name of this. I'm going to say multiprocessing, current process, and we want the name. From there, I'm going to say logging.info. Yes, assume at this point that logging is actually configured correctly and everything's just expected to work. We're going to cover it in a later section here, but just for grins and giggles, let's just assume that it's already set up. I'm going to say started. And then I'm going to say for x in range. And this is where we're going to just simulate some work here. We want to go up to the max. Let's go ahead and say logging.info. And let's just print out the name and the message here. Now we need to simulate like we're doing some sort of heavy number crunching or just something. So I'm going to say, let's go ahead and sleep for one second. Clearly, this is not going to win any Nobel prizes for complexity or anything like that. But basically all we're doing here is we're jumping in, we're saying, hey, get the name and then print out some information on the screen and then go to sleep every second and continue printing out over and over again. Just going to simulate some work. Now that we've defined the function that our worker process is going to use, let's go ahead and work with our main process. Now notice I called this the main process, not the main function, even though it's identical. So the main function runs in the main process. Let's say main and let's call the main function, which we have yet to build. Now before we do any of that, we are going to set up logging. We want to make sure that all this stuff works across multiple processes. Remember, the way Python interprets this is it's going to go in and it's going to configure logging based on the config, but it's only going to do it one time. And then some of the different versions may do this a little differently. So I put the logging config before I've even called main. So we're just going to make sure that's called no matter what. Now realistically, it should be configured here, but on older versions of Python, that's just has been no luck for me. So we're just going to play it safe because I don't know what version you're going to be running. All right, once we're here, we can go ahead and say logging dot info. And let's just simply say started. Now we want to actually pick up a worker process. So let's go ahead and call this worker equal. And I want to create an instance of the process class. We're going to say target. And this is going to be our work function. I want to give us some arguments. Let's say args equal got a handed list. And let's just say working. And then we need to give it a number here. So let's just take a step back. I'm going to make a variable called max. And we're going to put it right here max equals two. And this is going to be critically important to this little demo application. So really all we're doing here is we're calling this process with this function with these parameters here. Now max is going to do this range and that's going to be the number of seconds we're going to go to sleep. So this right here would say sleep for two seconds. That's going to be critical by the way this is going to function almost done. We're going to say we want to be a daemon. And let's go ahead and set this to true. Now we didn't do this in the last video. Let me move my mouse so you can see but we're going to actually set the name of this process. That's right you can actually name them. Let's call this worker. And name it whatever you want. It doesn't really matter. It's just a string. Go ahead and start our worker. Maybe if I can actually spell it. There we go. From here what we're going to do is say time dot sleep. And this is our main process. We're putting this to sleep and we don't do this very often if at all in the real world because you don't want to hang your program up. But we're going to say main process go to sleep for five seconds. There's a better way of doing this which we're going to cover in the next video but for now that's what we're going to do. Now we're going to say if the process is running stop it. This is a bit dangerous with processes. So you got to be a little careful. So we're going to say if worker dot is alive. And this is going to be a bull. We're going to say worker dot terminate. And then we want to say worker dot join. And we're just going to join that back into the main process execution. Seems a little confusing here. So really what we're doing is we're saying make a worker put it to sleep for two seconds. We are going to go to sleep for five seconds. When we wake back up if that worker is still running still alive and kicking in memory we're going to terminate it and that's a very dangerous thing. It's going to send what's called a sig term or a signal for termination which is going to tell that process. We are shutting you down and there's absolutely nothing you can do about that. Now think about that. Have you ever been like typing a note or an email or something and then the program crashes and you lose all your work? That's exactly what we're doing to that process. That is pretty dangerous. So we want to be a little careful on when how and why we do that. So from there we're going to say worker let's go ahead and join all that back into this main process and then we're good to go. And then let's just simply say logging dot info. I want to format that out. I'm going to say finished. And we want to get the result or the exit code back from that worker. Now this is different than returning a value. This is the actual process exit code. And what we mean by this is if an exit code is zero and I'm going to actually put this here. Zero. Maybe there we go. Exit code equals zero is good. If the exit code is not zero, it's very bad. And those exit codes could be operating system specific. They could be something that you as the developer would actually determine. But basically anything other than a zero for an exit code means something bad happened. All right, let's go ahead and let's get some screen real estate here. And assuming I didn't mistype anything. All right, started. Worker started worker working worker working and then finished exit code of zero. So it did work as expected. Now it worked because of our timing. We're saying create a process go for two seconds sleep for five. So we have three extra seconds. That's why there was that little delay down here. Let's see that in action again. You'll see started working working one 1000 to 1000 and should finish right about now. There it goes. That's why that works. Now watch what happens if I set this to six or actually let's just play it safe and set it to 10. So we're going to say start a process and run 10 times. But the main thread is only going to sleep for five seconds. When we wake up, we're going to say if that worker is alive, terminate that worker. We're going to send that SIG term that very bad thing. And we're going to tell it to shut down and you're going to see we are not going to have a zero for an exit code. It will be probably a 15 would be my guess. See this in action. So after five, it should wake up and then yep, finished negative 15. So that is the SIG term or the termination signal that we have sent to the process. So what happened in memory? This process was happily churning along and doing its thing. And then it died a slow horrible death or actually a very quick death. Let's go ahead and say logging dot info. And let's go ahead and say actually I'm just going to copy this whole thing just for a little bit of clarity there. We want to see when this process starts and when this process finished and we're going to rerun these examples. So let's go ahead and set this back to two. Clear this out. So you see our worker finished and then after a few seconds delay our main process finished with the exit code zero. So basically that's what join is doing is it's saying, hey, merge all that memory back together in the background, make sure we know what we're doing. Python gets all the information it needs and we can grab that exit code. Now this is the fun bit. Let's go ahead and set this to 20. Doesn't really matter as long as it's longer than our five. It's really not going to matter. Go ahead run and let's see this in action. Uh oh, you notice the problem. Worker working the worker never finished appropriately. That's why we have this negative 15, which indicates the exit code is greater or less than zero or I should say not equal to zero. That means something very bad happened. So as this process was running, it could have been on this line. It could have been on this line. It doesn't matter. The operating system came in and killed it and we lost whatever we were working on. So if we were building like a file or a socket connection or something like that, it just completely got obliterated. I hope you enjoyed this video. You can find the source code out on github.com. If you need additional help, myself and thousands of other developers are hanging out in the Voidrom's Facebook group. This is a large group with lots of developers and we talk about everything technology related, not just the technology that you just watched. And if you want official training, I do develop courses out on udemy.com. This is official classroom style training. If you go out there and the course you're looking for is just simply not there. You know, I'm either working on it or I will actually develop it. I will put a link down below for all three of those. And as always, help me help you smash that like and subscribe button. The more popular these videos become, the more I'll create and publish out on YouTube. Thank you for watching.