Async Techniques and Examples in Python Transcripts
Lecture: Demo: hello threads
0:00 Time to write some code about threads isn't it?
0:01 Alright, here we have our demo code.
0:04 This is in the GitHub repository under Chapter 5 threads
0:08 we have basic threads, CPU attempt
0:11 which we're going to get to these two shortly
0:13 but right now I just want to focus on sort of
0:15 the Hello World thread stuff.
0:17 What are the basics of threads?
0:18 How do we create them, how do they work?
0:20 What are some of their little non-obvious nuances
0:23 that we need to understand?
0:24 And then we'll go build a real program with them.
0:26 Here you can see a program called Hello
0:28 let's go ahead and run that.
0:29 It's underwhelming isn't it? Didn't do too much.
0:31 It did run, but then it just passed.
0:34 So let's go and do some interesting things.
0:36 Let's have a method here, say def greeter.
0:41 I want to pass in name, it's going to be a string
0:43 and the greeter, also let's pass in a times.
0:48 And that could be an integer.
0:50 So we're going to pass in a name and a number times
0:52 to do the greeting. So we'll just print out something like
0:56 hello there whatever your name is.
0:59 And then we're going to do this that many times.
1:02 And we'll go over here and call the greeter
1:04 and let's say Michael. Let's do it 100 times.
1:09 Well that's interesting but let's make it go slower.
1:12 Each time we're going to make it wait
1:13 so we can say time.sleep().
1:16 This will actually put the main thread to sleep
1:18 if it were another thread it would put that thread
1:20 to sleep as well and we'll release the GIL
1:22 which is pretty awesome.
1:24 Let's see if we can do this once per second.
1:26 So this should take a little over a minute and a half.
1:28 There it goes. What do you think, shall we just watch it?
1:31 No of course, that's going to be boring.
1:33 There's nothing to do with threads here anyway is there?
1:36 So let's start bringing threads into action here.
1:39 So the first thing I'm going to do is I'm going to say
1:42 import threading and keep it nice and explicit
1:45 like I do even for my production code.
1:47 I like to use the module name
1:49 the namespace style of programming here.
1:51 So what we're going to do is we're going to create a thread
1:53 call it just t. I'm going to create threading.thread.
1:56 What we're going to do is set the target.
1:59 The target is going to be the function, not calling it
2:03 but just the function name.
2:05 And then we're going to pass the args which are arguments
2:08 as a tuple and you know we can sort of just decompose
2:11 this really easily and just put that there.
2:15 Now if I run this it's not going to be so super interesting.
2:18 Let's do a little print done here.
2:22 What happened to our greeter? Didn't it say anything?
2:24 No, no no no it did not. Just because we created the thread
2:28 doesn't mean it's running. We have to say t.start().
2:32 There, wait a minute.
2:33 It was done and now it's still working.
2:36 That's weird. Here's the deal.
2:38 Our program, our main method, exited
2:41 but somehow this other thread is still running.
2:43 It's still, you can see it's still goin' on down here
2:45 doing it's thing. I'll finally stop it.
2:48 That's because by default, threads in Python
2:51 are what you would call foreground threads.
2:53 If any of those are running
2:55 even if your main thread that started your program
2:57 stops or exits, it's going to keep on running.
3:01 If you want this just to run in the background
3:03 if your program exits then the threads get canceled
3:07 then what we got to do is go here and say
3:08 this is a daemon thread.
3:10 Now we'll get a slightly different behavior.
3:12 Hello, nope, we're done.
3:14 Oh, okay well, interesting, there it goes.
3:17 That wasn't really what you were hoping for maybe
3:19 maybe it was.
3:20 So we started our thread but somehow we need to
3:23 do some other work.
3:24 We could say print, this is other work.
3:28 Like for example I could do math.
3:30 I could tell you what two times two is.
3:32 And then maybe after this point we don't have
3:34 any more work to do but we want to make sure
3:36 the thread still gets to finish its work
3:39 and just so we don't go insane let's make that 10 okay?
3:41 10 Michaels and we'll be good.
3:44 And we could even do an in here.
3:49 And print that out so we can keep track of where we are.
3:53 Okay so then down here if we say we don't want to exit
3:55 we'll say t.wait, no, join.
4:01 So remember I spoke about this fork-join pattern
4:04 the nomenclature here comes from fork-join.
4:06 I would prefer wait and you'll see in other things
4:09 in the threading world that we're going to get to
4:11 wait is sort of the newer style but, anyway.
4:15 Join it is, let's go. So we got this Hello.
4:20 This is other work for, so remember
4:22 computing for was our other work
4:24 and now we're doing the other things.
4:26 This is a zero-based loop, a computer loop
4:29 not a human loop. So we get this out here.
4:32 So we sort of kicked off some work, this is other work
4:35 and this is our main thread
4:36 our background thread is still working
4:38 and then when it's finally done
4:40 this line releases.
4:42 And when it releases after it's done
4:44 'cause the thread stopped running
4:46 we print our little final done and exit.
4:48 So now our main method won't actually exit
4:51 until the thread is done.
4:53 If it does because it's a daemon
4:55 that background thread and background work
4:56 will be immediately aborted.