 All right Thank you. Thank you very much. This is even though I've been doing Python for a while This is actually the first time that I've been to your old Python So if you're a first-time attendee come find me and we can talk about it here As far as the talk here, I could die threads had a number of people Coming up to me last night. There's I got this is some German joke or something like that. I'm like Unfortunately, no actually a lot of threads are gonna die in this talk So to just to start the talk off. I'm gonna throw up a sort of a deep thought to ponder here You know when threads sleep. Do they dream? I? Don't know what would possess someone to come up with that thought Maybe it's related to this tweet that I saw recently and because they were while you're pondering the first the first that there I saw Saw this I don't I don't know Jackson. I apologize Jackson I saw this and it's like hmm. You know what problem I'm trying to create with this code Maybe this is I'm gonna talk about like what problem am I trying to create with this talk? But we'll we'll get to that. Okay, so the thing that I'm thinking about in this talk is actually kind of the More stuff with the world of async. So there's been a lot of stuff with async programming going on in Python I've given some talks about various aspects of that and I'm not really gonna gonna repeat that here but one thing with with kind of the world of async is you've got this You have two different worlds of Python functions that have emerged you have the sort of the normal nice Python functions You know where you know the tomato case there and then you have this this async world of functions You know the tomato case, you know the famous song here And I'm really interested in the way that this that these two worlds kind of interact because it's it's sort of a very Interesting thing having a programming language with two different types of functions in there And where you can get into sort of strange things is if you try to mix these two worlds together Like if you try to write a normal Python function and then all of a sudden you try to go into like async The way you call an async functions with a weight you're basically gonna get shut off doing that Okay, it's like Python hates that it's like can't call async from the world of synchronous code But you also run into problems if you go the other way like if you're if you're using async I o or async or something You're writing async functions, and then you decide to execute like a like a synchronous, you know normal Python function in there What happens at that point? And anything could happen. I mean it's like a normal Python function It could launch a thread it could block it could go compute Dibonacci numbers or mine bitcoins or whatever it's it's sort of there's sort of there's sorts of lots of problems with that So I kind of look at this situation. It's like, huh That's just weird. It's like okay Yeah, it's like you have these two these two worlds of functions, and there's all sorts of bad things that can happen so Stepping back from that a moment One of the things that I that I kind of ask people when I teach and meet people is is this question of Why are you using async program? This is a big question, you know it's like why would you go into this world of async where you have all these async functions and so forth and Typical answers that come up or things like wow or we're Twitter or a Facebook or something like that It's like oh, okay, but that's probably a good use case I mean one one benefit of async is large scaling large lots of clients and so forth But a lot of Python programmers like myself. It's like I'm not Twitter I'm like, I'm not doing things at that kind of scale. Okay, so I'm not really so interested in that Another question, you know another response I sometimes get is well I think there's the the global interpreter lack and I sort of feel bad about that So I sort of blew up the the gill like eight years ago and some talk and everybody points at it And it's like a Python evil because of the because of the gill That's a that's a little weird too because if you get into asynchronous program It doesn't really solve the gill. I mean you still have it. It's just you're just getting rid of threads I mean, it's it's like you're not getting any real benefit related to that. So I'm not I'm not so interested in that either. I mean, we're not gonna we're not gonna fix that problem But then there's this this third thing that comes up, which is just people's impressions of threads I'm sort of curious. I mean how many people have done thread programming in here At one point or another. I'm a little bit curious if your experience with thread program It's kind of like my experience with thread programming. So you run some thread program And then just sits there and like nothing happens And then you and then you like hit control C and then like nothing still happens And then you hit it a few more times and you're like Sucks and like finally you have you control Z the whole thing and then you have to find your like Python Process and then like kill minus nine or something like that. Is that Yeah, okay, so Now we're getting into the German part of the talk here and then die die threads die here No, this I think that's like a common experience of threads as you do this and it's it's like oh It's like tear terrible experience there. It's not just this though. I think if you look at threads If there's a lot of just weird stuff about it like like even creating a thread is kind of annoying. I Haven't teach people in classes. It's like hey, this is how you create a thread And they sort of ignore the whole thing that's up here and then focus on like the one tuple and the at the end Like why is it five comma and then there's a whole discussion about that and then Or the only way to create a thread is to use everybody's favorite and feature which is inheritance obviously I mean you gotta do that. So, you know, like creating threads is sort of weird Communicating with a thread is sort of annoying like let's say you have a thread and and you want to return a result back You would think that there would be some easy way to do that like you start a thread and then you join it You get the result and like No, I mean it's like threads basically you launch them and they just sort of fall off the end of the universe or the Edge of the world The only way to get a result back is you you have to arrange for it Maybe you mess around with futures or some other other thing But you know the code is already kind of making me you know kind of cry a little bit with the with the added complexity And then and then you get into things like can you cancel a thread or kill it or something? I mean this is a whole you know a whole big topic that will Get to in a second, but it's like if you want to kill a thread. You're basically on your own You know roll on the floor laughing kind of kind of kind of thing with that if you if you do some searching online by the way you might find people saying like Well, actually have you considered using C types to kill us and then no like You'll find answers like oh you can you can like just directly go into like the POSIX library or something in nuclear program using C types like Don't do that. So so I think about this this like thread experience and it's like this is just bad But they basically work I mean for some definition of work I mean one benefit of threads is you know, you can run normal code and threads Probably works. You don't have to rewrite the whole universe. So I mean you kind of you kind of get that but it's still not a great great experience and Maybe because of that experience that is is maybe a big appeal of some of the async stuff I mean it's in some sense. It's like a new you know It's like a new starting point and maybe an appeal is you know, you can kind of rebuild the universe or something it's like let's do it right this time and See what see what happens. Whether it's gonna end up like the slide on the right I don't know but it's you know kind of you know kind of kind of rebuild things and You do see this I mean there's there's a lot of people working on async live like versions of async libraries to do different things like HTTP and requests and database and Redis and all this all this stuff and this is there's actually a lot of very interesting Things going on with this I mean if you look at some of the talks on it and some of the work I mean it's there's some there's some cool ideas, you know like that like the sans IO stuff trying to get rid of IO and So forth but but I'm sort of looking at this and thinking about it had this sort of thought like Couldn't you just rewrite threads Or maybe could you re-envision threads? I mean if we're gonna re-envision everything else Maybe we could re-envision threads at the same time. So I'm gonna do a little Experiment of re-envisioning threads here. This is gonna do is involve some live coding and some demos And it's it's more of a of a thought experiment And I just want to I want to preface this by saying this is nothing that's suitable for any kind of production or anything at this time this is purely Purely experimental. So the thing that I'm kind of thinking about is You know, what if there were like a replacement thread library? I don't know. We're basically gonna redo threads That's kind of our our thought so me so maybe I'm gonna have some library that involves the word redo I don't know. Maybe we call it thread. Oh It's a bad name, but you need a you need a cute name for your your library there Actually, thread. Oh sounds really awesome if you've lower your voice and you said the right. Oh or something Actually, don't don't do that. So so imagine that you had like a This sort of new thread library And you tried to fix like all these problems that you hated about the old one So so maybe just like like starting off. Let's say Let's say you had a simple function like that And you just wanted to launch a thread and get the result back I would really like to have some easier way to do this or you could just say well Let's just spawn that function with those arguments and Then just get the result back Maybe maybe you do that Don't have inheritance. Don't have the one tuple. Don't involve futures and all this stuff Just just try to do something really simple like that And and see what that would look like now see if I can find my curse area So run that maybe we'll call this ex ex one here. Oh, and you have to give it an argument here, okay? You guys have to do debugging in the in the talk here Okay, so maybe you could maybe you could just start with that just give my thread just just a better Experience from the start basically. It's like okay. You have a function. You can call it You can get you can get the result You might be able to do some things with errors as well You know, maybe like let's say somebody called this with a like bad like bad types or something Instead of instead of just having like right now with threads if you crash They sort of print a message and then disappear off into the vapor or something like that Maybe you could just take that and have it return Like a wrapped exception or something one feature of python 3 is that you've got these these like Like these chained exception objects so you can you can basically package up exceptions and kind of a nice way Maybe you do that let's just try running that Okay, so it failed and you've got a type air so one thing on on on this this Hypothetical, you know sort of new thread things like you just sort of you know fixing the way that you launch thread The other thing that you would want to do okay, so let's let's do another next next thing you want to do Example to here is actually make sure that it's real thread like you actually have some kind of actual concurrency going on here so Let's let's write a function that that that Basically takes like a counter and some label and then maybe maybe does like some very intensive CPU calculation with it This is not the most interesting example perhaps, but what we're going to do is just Create a running total will decrement in and Then maybe every so often will print out something Do people know you can you can do the underscore in numbers in Python now? Kind of a nice kind of a nice thing so Maybe you have a function like that one of the things that that we should have in this thread library Is the ability to spawn like two of these things? I know let's count down from like 60 million We'll call this one thread one so the label is just so that we can see them the different things are on Okay, so maybe maybe you have code like that. Okay looks looks sort of like thread You know slightly different interface, so we're doing is spawning that function off You know twice and we're just mainly what we're going to do here It's just see if they run at the same time One of the things just to note if you if you were to do something like this in like an async framework Launching a big CPU bound dot job like that would just grind the whole thing to a halt and then nothing would happen until it's done So we're trying to not we don't want that. Okay. Let's let's run that here Okay, so this thing is this thing is kind of turning along and You see both threads making progress. They're both kind of going at about the same time printing stuff out so One of the things that you have here is it basically is real threads. It's not you know, it's not Greenlets, it's not async or anything like that. So it actually is a you know, you do get the kind of the normal concurrency there But the the next thing that you want though and this is this is where the death is gonna start. I apologize for that It'd be really nice if you could actually have these things die in some some way I mean that that's the thought that most people have with threads is you know, can you Can you make them die in some way? So let's say you had a function, you know, that just did something trivially dumb here like maybe sleep for like 10 seconds like like that We're gonna we're gonna launch it and then we're gonna we're gonna sleep our well. Let's just let's just wait for it here There's no results coming back. So I'm just gonna wait from it. So so what this is gonna do is Just sleep for a moment and then Ron I keep missing that main at the end there Your job is to catch me on all typos by the way. So, you know see see something yell it out Say hey, you're forgetting something. So so this thing is is sleeping for 10 seconds Then comes back The thing that would be really nice and this is the thing that threads cannot do is just have the ability to Kill them brief Immediately like can I do something like that? So instead of waiting for it. Can I just cancel the thing? Let's try that and see what happened Okay, so yawn and then it just comes back when you never see you never see a return at that point Essentially what you what you've got here is like a cancellation mechanism built into threads where it's where it's just like We're done with it cancel it. The other thing that would be nice about that Would be if you could catch it in the thread itself Like maybe you could wrap this with a with like a try accept or something and do something in response to it So let's let's let's try that Okay, so it comes back and it's like I canceled it So so this is kind of a kind of a starting point. We're gonna do more with this in a in a second but the idea is Reenvision threads a little bit. It's like get get get rid of the crazy creation process get rid of the The the lack of ability return a result and then add these this this cancellation stuff into it now keeping with the title of the talk Kind of want to run with this cancellation idea a little bit This is actually I think a really big point of some of these acing frameworks is that They actually give you a lot of control over what happens on the in your program I mean, that's actually a feature of these frameworks is that you have sort of control over what's happening And a big part of that is actually being able to to like cancel work or to schedule work and to do other things This is something that has never traditionally been possible with thread programming at least not easily So I kind of want to I kind of want to just roll with some different examples on that One of the one one example that you might consider Is how this might interact with something like a lock? Already we're in dangerous territory here actually as an as an aside If you ever read about thread cancellation One of the things that you'll commonly encounter is like comments like never do this And then usually there's like a big long line like laundry list of wine locking is usually at the top of that list Here's an example of What I'm talking about here. Okay, so I'm gonna write a function that Just sort of starts off The argument is going to be a lock of some kind and what it's going to do is basically acquire the lock Do some work maybe it will sleep for a little bit. We'll sleep for five second and then Come back like that and here is the issue with with locking Okay, so let's say your library had some lock object Threading library should actually have different kinds of locks. Maybe a lock I don't know. Maybe you want a semaphore or something, you know, classic kinds of like threading, you know primitives like that and What can happen is you might spawn like two different jobs like you could say well, here's here's that function on lock You know thread one There's the same function on the same lock Very two and let's let's wait for I'm here Okay, so we're gonna we're going to wait for the for the two threads here And let's let's just run that to make sure that that Does what we want here. Okay, so what you should see is it comes up thread one starting thread one working Thread two basically had to block there because it had the lock It didn't what didn't have the lock and had to had to wait So what's happening is like the two threads are basically prevented from working because of because of the lock now that the interesting case with something like that is What happens if you decide to cancel one of those things like like like case one What if you cancel the thread waiting for the lock? Like let's say you do it like a little bit of sleeping here like you sleep for like two seconds And then you just come out of the blue and you're like that thread to I'm gonna I'm just gonna cancel you And then I'll join with thread thread one the question is like what happens there I mean essentially you have this thread kind of waiting for a lock Does it does it like cleanly step away from the lock when you do that or to some other kind of bad thing happen there? What you would like is you would like it to sort of cleanly step away So what would happen here is you know the threads would start get thread one working Thread to done and then you just never see anything more from thread to it's like Basically, it got canceled and it's like yeah done done with that The the more evil case though, and this is this is why a lot of people would tell you to never do thread cancelation Is essentially the the opposite? What happens if you cancel a thread that holds a lot? It's like what so you flip it around and you just decide to cancel thread one and then join with thread two The reason this is evil It's like you have this lock you go into the code and then all of a sudden it gets like a cancellation It's like what happens to that lock I Mean if you don't give up the lock I mean essentially your whole program is just gonna die like a horrible death They're actually it's not even a die It's just gonna sit there, and then you're gonna do like a kill minus nine on it at some point So so that's that's kind of the more the more evil case is that so let's let's try that What happens here is it kind of went into thread one working? And then it just sort of never came back The reason it never came back is it is that it got killed basically? You never see like a thread one done thing So so something like that Works works as well. So in it's kind of this new thread library. You've got I don't know you have the ability to like cancel locks just as one comment on this I think one thing that probably makes this sane is Python's with statement That is actually a really amazing feature of Python is the with the fact that you can like use a resource and have it properly cleaned up When you're when you're done with it that is what's making this kind of saying It's like if you get if you get some kind of cancellation showing up It does show up as kind of an exception in that code, but you can back out of it You can clean it up and you can release a lock All right, so with me on that doing doing thread cancellation stuff You could take this further by the way We'll see how we're doing on time You could look at more complicated kinds of problem like one famous problem from From kind of operating systems would be things like the dining philosophers problem I don't know there you've seen that or not But basically the problems you have like five philosophers sitting around at a table and then on the table You've got five chopsticks, so maybe that you have these These chopsticks on the table which are represented as locks Okay, so you have you have five chopsticks, and then you have some philosopher process That essentially just wants to eat and the way that it eats is maybe it sleeps for a certain amount of time So we're gonna do like a like a random sleep here And then in order to eat what it will do is acquire a lock So it will do Like one of the sticks it will acquire that Maybe it sleeps a little bit more Philosophers spend a lot of their time thinking right so if you grab one chopstick, you know You might think a while before grabbing the second one there So so the idea is you have these these like two Two chopsticks that you need to acquire Yeah, I see that the Trito or Tretto now I can okay Maybe it sleeps some more Am I missing a oh Sticks, yeah, see this is this is why I don't need a fancy ID. So I just use the crowd Yeah, okay. Yeah, okay, so Eating okay. Yeah, it's like like eating and here. Okay, so so you have something you have something like this, okay, so maybe Maybe it sleeps for a random amount as well And and and so maybe that's your your program. You have kind of the the philosopher thing Like that and then what you're gonna do is is maybe launch these into into threads And then we'll maybe wake up wait up wait for him. Okay, so We'll see if this works famous famous last words of this if this Am I am I missing something else here? Oh? Yeah, okay. Yeah that one. Yeah, okay And I like this this Wait just means that they don't like if you're not if you don't care about the result you can just wait for Join will return a result if you want it, but Maybe maybe you want the old behavior, you know, so let's just just see what happens there So so that code the first time I run it it seems to work That the big reason why people care about the the dining philosophers though is that oftentimes it does not work We'll see if it fails. Okay, so right now It's basically not doing every anything at all that the problem here is that the basically that just to the prom is in order to eat You need two chopsticks, but there's only five and what has happened is like every philosopher has reached out to one chopstick And then nobody can make any progress, right? It's like okay So the whole thing is deadlocked up to the philosophers all starve and die and now we're into like that the dying philosopher Talk and it's like you know, that's it's bad there So so so you spend a lot of time like operating systems, you know thinking it's like well, okay How do we avoid this? How do we make the philosophers? You know play nice with each other and and and so forth We're not gonna do that because you know the age of diplomacy is over so you know kind of kind of thing so so instead what we might do here is We could maybe we could just drop like a timeout on this thing like we could say like you know with with you know, thread-o timeout after I Don't know after 10 seconds or something so we're gonna we're gonna try to do this This like waiting thing and then instead of trying to avoid deadlock We're just gonna do like a Deadlock recovery thing. This is this is by no means graceful, but what we'll do is We'll pick out like a random philosopher And we'll just cancel it but the thinking here is that you if you if you just if one of the philosophers dies It will drop its chopstick and then the rest of them can make progress Yeah, I gotta gotta fix that so so we'll do we'll do that. I don't know. Let's let's let's try Let's try running that actually, you know if the philosophers do have the option of dying Which probably should give them like some option to ponder it briefly actually so I put it put an F string in there just for extra effect there. Okay, so So let's let's try. Okay, so Okay, so it looks like it's like maybe immediately immediately dead already here deadlock What was my timeout 10 seconds? Oh Random it. Oh, okay Well, you got you got that you did see the timeout there So let's let's let's try it again Deadlocked deadlocked again. So the thing is kind of it's it's it's wedged But if it's working, right, it should just pick a random philosopher and then the rest of them the rest of them wake up But what is there okay, so that is that's actually kind of cool It's like, huh, you had like thread holding, you know holding locks and just blow it away and like everything Everything everything works of course diplomacy is not Restored there, but then it's okay, so that's like another another example Some other things that you that you might want with this this thread library. I don't know what example we're up to here Would be things like chewing kinds of stuff one common thing that I that I often have to do in In in thread code as I often do like producer consumer types of problems like, you know Creating worker tasks and so forth like maybe you have a queue We'll do something like this like item is equal to q get By the way, this this would be one place to use this new like pep 572 stuff Not to not to open up that battle in this talk, but you could you could do a while item, you know Equals q yet or something but let's stay let's stay away from that. Okay, so But you okay, so you could do you know while true get the item Maybe I'm gonna catch like this this accept exception here. Okay, so I kind of do this stuff with with workers a lot So here's here's what's gonna happen here Maybe you want to create like a like some kind of worker pool Okay, so you're gonna you're gonna create like a like a queue of Some kind and then what I want to do is I want to launch a whole bunch of workers But I want them to be under like some kind of central control of some sort One of the things that's really cool that's going on in kind of the async world right now is A whole bunch of stuff with like threat like task groups and Cancellation sorts of stuff. This is something that that Nathaniel Smith is working on a lot like the trio project If you've encountered that so it would be really cool to have something like that In our in our thread library like maybe we could make like a thread group of some kind Where you create a group of threads and then you could you could basically launch like you say, okay I'm gonna make like four workers. I don't know. I'm gonna give them a label here Just so so you can see that so so what's gonna happen is you're essentially gonna launch like a bunch of workers under the control Of like a thread group or something and then I'll feed I'll feed them some work like maybe I'll Just drop stuff onto the queue I'm gonna slow it down a little bit just so you can see it work So we'll we'll we'll feed it on to the queue there One thing with cues by the way is they do have a signaling mechanism in there This is this is basically from Python standard libraries. You can do a task done So come down here and then I'll I'll join with the queue And then one of the problems that you have with these work cues is how do you get all the workers to shut down? I don't know whether anybody's encountered this problem of like you launch something but then you have to have it shut down A common way to do that is maybe you put like a special value on the queue like a none or some kind of sentinel or something like that We don't want to do that We just want to we just want to nuke everything. It's like cancel remaining and then like we're done essentially so So we would really like to do something like that so it's like spawn workers You know give them some work join with it and then and then when we're done just you know Just clean the whole thing up So let's see if that were oh no, well G is the group But Q is the queue it turns out queues actually have a join mechanism on there There's like task done which sort of tells you that you did something with it And then you can use a you can do use join to basically wait for the queue to process all the things so That's a great question, and it's very subtle. It's like it's a place where I could have made a mistake actually but no we're waiting waiting for the queue to kind of kind of finish up, but That's That's kind of cool. It's like just canceled canceled all the things Turns out you could probably clean that up even further One of the things that that is sometimes done with these like thread groups or task groups as you can give different policies for how to how to process it What I'm doing here is I'm saying well make a thread group weight equals none that that's sort of the we wait for nobody policy And what happens is if the code ever leaves this with statement? It will just blow away any thread that was still active at that time So so you can do some some some modifications like that Oh Like the ordering of that. I I don't know. I don't know you want it to be predictable It there is some some element of fairness in that but that might be an accident So I'm not I'm not willing to bet bet on that one one thing. I also Do want to talk about I? Want to go back to this spinning thing for a second here I had this example with CPU bound tasks at one at one point I want to emphasize that everything that's going on here is thread code I mean it's it's like if I if I were to come in here and just say like thread oh spawn Spin at the start of this thing and then run it you will see it Oh, I have to give it some arguments here like like spin from like 60 million Like that and and run it you will see that running concurrently with the other code So it's like it's getting workers and then you see the spin stuff happening at the same time The presence of that CPU bound loop It's not shutting down the rest of it like so this is not this is not async. That's that's going on here I also want to want to point out that that this that the cancellation on this is also not Totally Unconstrained it turns out that if you were to put that spin thing like Like on a like on a thread group like that Like let's do like maybe a hundred million or something like that The code will That will work But you can't actually cancel anything that is spinning on the CPU That is Actually, it probably a very good thing in a thread library. It turns out if you allow something to be canceled It's done some random instruction. That's really bad So in this in this framework the cancellation actually can only take place on things that block So so things like get operations Blocking on sockets that that sort of thing. Okay, so so that's that's kind of a kind of another another interesting thing Now a final thing. I'm getting kind of a five-minute timer here. We're almost almost done You would definitely want This thread library to be able to work with things like sockets and other Things for like network programming. So the final thing that I'm gonna that I'm gonna do here Is Do a die request exam now? This is not that I okay. This is not that I love request What I'm talking about here is it would be really cool if you could take like this this library you know like the thread oh thing and Then let's say throttle had like I don't know some kind of magic thing that you could do We're not gonna get into the details of that but like let's say you could Yeah, you don't want to know that import request and then maybe I don't know. Maybe you could have some function where You you fire off like a like a request somewhere But you you have the ability to cancel it. Okay, so maybe you do something like Do something like this like this you'd say, okay, let's let's make like a thread group We're gonna wait for anything to finish And then we're just gonna fire off a whole bunch of stuff here Like let's let's go spawn like the function off So we're gonna we're gonna we're gonna spawn like four copies of this request thing off And then maybe we'll just print out the result of the one that completed Yes, we'll talk later. Yes You know, yeah, yeah It's the only way to get the cool highlighting on it Are you are you horrified my improv probably yeah, okay, so so so the so the idea here I hope that this server is ready. So we're gonna fire off request to a server four of them kind of in parallel and then the idea is I Want to I want to print the result of whichever the first one that finished is like slight indentation problem there So let's let's try that one Task group connection error. I might have like me. I might not have a server running on that So let me check it real quick here. Let's run that again Okay, so this thing is it's kind of just sitting there. It slowed down on purpose. So waiting Yeah, we're getting another error there Well, I did get it canceled there, okay So so the idea on that is it basically did get a response It's something happened, but then it canceled the it canceled the other ones I had a little bum that that didn't work, right? Let's try it one more one more time here famous Famous last last words here. I can always use my excuse that it worked this morning, right? Oh Okay, they're a that's that network. Nothing ever works on their right work So so the the the what happened there is basically fired off like a bunch of things to request four of them and Like three of them were canceled because the result came back and the last one came back with result dye threads That that was the response from the other the other machine there. So This is the kind of stuff I'm thinking about in this kind of re-envision Thread framework, you know, it's like okay We're gonna let's re-envision threads Most of it is about just killing threads because that's like the best thing to do with threads is to see them die And and so forth but but it I think it's like more than that It's actually just having a lot of control over what the thread and like what can you do with threads? Can you do like main way more of a thread? Can you put them in groups? Can you kill them? Can you get results back? Can you just totally re-envision? That that thread programming interface And what would it be like to do that? I don't know what you thought of that demo But I think it's kind of I think it's kind of cool. It's like, huh That's kind of interesting and it kind of brings me back to the opening slide So when threads sleep do they dream? Here's the gist of this talk Do the dream of the kernel and by the kernel I mean the operating system Like is that our threads when they're asleep? Are they sitting there dreaming of like icy planes of penguins like flapping around and like, you know Linux and all that kind of stuff like they are dreaming of the kernel or They dreaming of an async event loop What you saw in the demo is that It's a re-implementation of threads on top of async It's a very interesting kind of concept But I have to give you like the French ending to this talk where I just leave you hanging like how in the world does that work? So we're pretty much we're pretty much out of time. I Guess the thought on the talk was maybe just kind of throw kind of an interesting wild concept out there And you want to find out more about it? You're gonna have to track me down and answer ask questions and so forth So that's that's pretty much the end of the talk. We may have time for questions or not. Do we have time for questions? There might be questions. I don't know a few questions, but let's see if there are questions here Thank you very much. Thank you very much David Was a great keynote. So if you have any questions, please we have two microphones in the front Okay, you have to walk here. We don't bring the microphones as usual so if you have a question queue up and we maybe have time for Three to four questions and please keep them short and while first people fighting to their way to the microphones Please always remember Questions are about asking something and not about yourself. Thank you Okay, so that works So you shown those threads that do CPU bound stuff and they work Concurrently yes, and it runs on a event loop, but it's is it's like does it actually use a couple of courses like multi-processing or not or it did the so the multiple threads running on that you saw running concurrently they are Actual Python threads and they are subject to the same limitations of the gill. So there is the gill There's a you know the global interpreter lack. They were just created in a slightly different way Okay, so a bit mysterious but it's miss a bit. Mr. I might I might uncover the mystery here in a second. So yeah Let's see. That's great. Thank you. I was just wondering are you actually using the new editor? Every this is just for the no, I know I I am using the question I mean am I using the mood editor and the answer is yes I did modify it to take away command completion though Because I don't like but I don't like windows popping up during talks and stuff, but no, it's them. It's the mood editor One comment just a side comment I'm really interested in editing environments for Python beginners And I've used idle for a long time and teaching classes. I'm kind of excited that move has Has come out in a way that can run to standalone. I know it's very early, but it's it's kind of it I thought I'd try it out. So Yeah Have you gotten as far as building an actor model on top of straddle and not not with this project now What you've shown us they're crazy and evil at the same time as usual What I was thinking about The thread or sleep function can be cancelled, but time sleep cannot be cancelled How can you tell the difference if you just see a sleep and you don't know whether it comes from thread or time if That function can be cancelled or not. So You are actually on to something very critical with that it turns out that in order for this this library to work You have to use the functions that it provides like thread of sleep like thread o lock thread o queue and so forth It is very analogous to these async frameworks like if you use threads and async IO or not threads But locks and async IO you put you have to use the async IO locks and cues and so forth to do that If you choose to use the other sleep like let's say you use time sleep or use the regular threading lock The code will still work, but you lose cancellation. That's the only thing that you it's it's essentially like well Because you're not using my thing You can't you can't cancel it So that the worst penalty would be would be that you're actually on to what is happening in this library I kind of anticipated that that people was like what in the world is going on in this thing here is Here is the basic gist of this library If you're in a thread and you block You block in the operating system kernel you work your way down from Python you go into C Python You go into libc you hit the OS kernel and you're in the kernel and you're like dead at that point You're not coming back until the kernel says that you're that you're dead The gist of this talk though Why does it have to block in the kernel? No, like why does it have to block in the operating system? Why not block on an event loop? You have async IO you have event loops you could go block over there like this, you know like basically sleeping is sleeping it's like Doesn't matter where it takes place and so you know I mentioned it's like this is a thread library implemented on top of async It's actually running an async event loop in the background and every single time it does a blocking operation It essentially says you go block over there like blocking the event loop And you know tell me when you come back So it's kind of it's sort of an interesting, you know kind of weird weird thing But that's that's what's happening the reason that it and because it does that is why you have to do the special Like you have to use the special object because they're programmed to do this like sit like redirect Okay, thanks. Okay. Yeah Did did you build the interaction between some async code and some thread O code in the same code base yet? Oh Oh, yeah, so this is so this whole implementation is Written on curio. I don't want this to be like a like a curio talk But that it's essentially using a feature of curio that allows threads and async to work together So in that context they do work together I Wouldn't say that's like specific to that library. I mean you could make it work with other stuff. I just haven't so Okay, so the last and final question for this keynote So thank you great talk. Could you explain a little bit what's going on with the more magic? Oh more magic had to ask about the more magic thing The the more magic thing so in so in order to get this to work with third-party libraries like requests Mainly what I need to do is I need it to use my socket object turns out that thread O has its own socket object The only way that I can get it to work is to for it to use my socket object So it's essentially what I'm doing there is temporarily replacing the socket module with a replacement It's it's it would be like using the monkey patching and like G event or something Preferably, I would not want to do that. I mean you can actually get requests to work without Monkey patching the socket module, but it involves this really crazy chain of inheritance and making like session objects and other Other things but but that that's why that that's what that was doing is essentially just getting it to use my socket object instead of the Hey, thank you very much David Yeah