Qt 6 - Episode 21 - Intro to threading

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everybody this is brian and i am back from summer vacation i had a great summer but it's simply time to start recording again so this video is going to pick up where the series left off but we're going to jump right into the scary deep end we're going to talk about threading so this video is an introduction to threading if you already understand the concept of threads and threading use the buffer bar below to skip ahead to the section you want to see we're going to cover what is a thread why do we use threads how cute uses threads and we're going to wrap this up with a very simple threaded example i have to stress it's going to be a simple threaded example because threading can get very complex and the next few videos we're going to dive into that complexity let's take a look so what are threads well prepare to be very very confused because this is computer science 101 if you are a newbie computer person or a newbie programmer you may have some questions we're going to turn to wikipedia and we're going to look at the simple thread in terms of computing you can read this very straightforward at least to me it is documents but uh you're still going to be very confused so fortunately they have this graphic and well this is also confusing but let's break it down here so you have a program this is what we as developers create the actual program now this is the binary that exists on the hard drive when the operating system runs your program it creates an instance of it in memory so what does that really mean well your program can be created and run in memory multiple times we call those processes so each process is a copy of your program now each process or each copy of your program can have multiple threads and this is really what we're talking about in these videos what is a thread well you notice these numbers number one two three four you have instructions one two three four when you see the term instruction think of that as like lines or blocks of code so for example you could run instruction one instruction two three and four on different threads one two three and four now these don't line up one for one that's the confusing part just because you have instruction two doesn't mean it's on thread number two the operating system really determines where things run so to rewind you have a program it is on the disk it gets loaded into a ram as a process that process will talk to the scheduler usually in the form of creating what's called a thread class which talks to the actual operating system and what the scheduler here does is it says oh you want to run these threads these threads line up with some instructions i'll figure out the best place for them in the cpu and run them for you meaning we have very little control over this part right here all we do as a developer is we create the instructions decide how we want them threaded and then ask the scheduler pretty please thread them for us now if all of that seemed overly simple there is a lot of complexity to threads that we're going to talk about in future videos you're going to hear some very confusing terms like semaphores mutexes mutex lockers things like that don't worry about those yet we're going to cover those in future videos at its core really what we're talking about is taking a block of code running it through the scheduler and putting it on the cpu now modern cpus are very very powerful i'll give you an example i'm going to look at system monitor i'm on linux but virtually every operating system has something like this i have one physical cpu and that cpu has eight cores so i can have eight instructions running simultaneously actually i can have many more than that based off how the scheduler works remember this happens very very quickly so even if i only had just this one cpu the scheduler will say run instruction one stop it and run instruction two but it does it so fast it appears they're running at the same time this is incredibly powerful and honestly the more cores you have and the better performing os you have the faster your program's going to run one question you may be asking is why even use threads this sounds super super complicated and it can be to be brutally honest why even bother with it well the answer is very simple a process with two threads of execution running on one processor this little image here is beautiful because you have a process an instance of your application with multiple threads running at the same time meaning you can do more than one thing at a time you ever have to do that like in life at school or at a job where you have to do multiple things at once like type and talk on the phone that's exactly what we're telling our process to do let's take a look here so we have a physical cpu and we have some instruction a piece of code here now typically what we've done and let's just make a couple of these is we've got different instructions instruction one two and three now these are just blocks of code or functions whatever you want and they would just go in order one then two then three very very slow right because two is not going to run until one's done and three is not going to run until one and two are done so it takes time to get there yeah no we don't have time for any of that nonsense we're in threading land so what we're going to do here is we're going to thread these and here is our cpu now inside i shouldn't say inside but also including this is the scheduler so we're not talking directly the hardware we're talking to the operating system so let's just say os slash cpu and then we're going to say hey well let's put it here we're going to run this one we're going to run this one and we're going to run this one pretty cool right so now we can run multiple things at the same time now if you remember you may have more than one cpu for example i have one physical cpu but i have eight cores well let's just take this and what we're going to do here is just represent a core let's shrink him down this is where the complexity gets a little bit weird so the operating system is going to figure out the best place for these we don't really get to say you're not going to say run this on core 2 it just simply doesn't work that way you just say i want to run some instructions i want them multi-threaded the operating system figures out where they need to go and it puts it on you guessed it the right area here so this is a very high level of what we're talking about you can do multiple things at once the operating system is powerful enough to talk to the underlying hardware and figure out how to do those multiple things at once the end result is your program can be multiple times faster and i am not even joking i have seen programs once you switch to a threaded model will go from say one to two minutes down to a second or they'll go from an hour down to maybe 10 seconds i mean it literally you can have that kind of speed boost if you design your applications appropriately as you might have guessed this can get very confusing very quickly cute however makes this very very simple so we're going to take this and we're going to modify it a bit we have multiple instructions inside of our application and then i'm going to take this and we're going to say this is cute and what cute does is it allows us to take all of this code put it right through cute and we're going to use a class called q thread now cue thread is a bit mysterious what does q thread really do well you can take different classes like cat dog bird that have full sets of instructions in them and say i want to move this to the thread we're going to take him and we're going to grab him and say move that right to a thread and then the thread and talk to the operating system in the scheduler now unfortunately the confusing bit is you're going to think hey i'm going to move all these two but when you do that they all run on the same thread so you don't want to add them all to the same thread typically what you would do is have multiple threads something like this so you'd say i want cat and preferred to be on different threads than the dog and then they would of course under the hood talk to the operating system and the cpu so this is really what we're going to be doing in this example that we're about to do we're just going to take one class and move it to a thread and then run it in a multi-threaded fashion so you can see how it actually flows just bear in mind that if you don't do it like this like if you were to just get rid of these do something like this what's going to happen well let's say you have a cat doing well what cats do and dogs doing what dogs do and birds doing what they do they're all going to run one at a time on the same thread so you want to avoid this type of situation here let's take a look at a very simple example again i have to stress this is the simplest example i could probably think of so i'm going to start this from scratch but in future videos we're going to start with a program that's open and ready so i'm going to make a console application and let's call this cute six episode 21. next when you use cmake as the build system and whatever kit you have i realize there's a newer one out i haven't installed it yet doesn't really matter there's not a lot of changes all right let's go ahead and there'll be a little bit of copy and paste in this video but i'm going to plop in some notes real quick all right so we're going to create a cue thread we're going to move an instance of a class to it and it cannot have a parent it's very important that if you remember anything from this video when you move a class to a thread it cannot have a parent there's a reason for that all right so let's go ahead and right click i'm going to add new i'm going to make a class i'm going to call this worker this is going to be a cue object so it has signals and slots and all that goodness baked right into it next and finish now we need to of course update cmake and because i'm coming back from summer vacation i'm a bit rusty on the typing so forgive any misspellings all right now we've got our worker here we're going to do two things right up front we're going to put in q thread and q to bug and q thread is built right into cute core so don't worry about that but what q thread does is it provides a platform independent way to manage threads yes i am aware that c plus specific versions of it have this baked into it but we're talking about cute and how cute does threading you can use the standard library thread model if you want but obviously in this video we're going to cover the cute threads so we've got our worker and we're going to do two very specific things here we're going to make a deconstructor and a public slot called run the premise here is when we move our object to the thread it's not running yet we have to tell it to run but the worker won't magically know when the thread starts so we're going to connect these two with signals and slots when the thread starts it's going to call our run slot so let's flesh these out real quick so inside the worker this becomes very very simple and i'm going to just copy and paste a little snippet here so we're going to say cue info and we're going to print out this current object and we're saying constructed and then this little bit of magic here cue thread and we want to get the current thread so we're just going to print that out under the hood the current thread is just simply a q thread which is also a q object so it has signals and slots baked right into it and we're going to say deconstructed now what we're going to do later on is we're going to name that thread so you can see on the screen the difference between the main thread and the worker thread that we're about to create now in this run function when this thread actually runs we're going to do something a little different i'm going to say 4 and i and let's just go up to 10 and we're going to go ahead and increment i very simple little loop here now i'm going to just grab this to save a smidge of typing and we're going to say this working and then we want the integer here so let's go ahead and say we're going to convert that i into a q string and then we're going to print out the current thread we can if we want to get rid of that right there so very simply just going to save working and then the number that we're on and then our current thread that we're running on notice i said of the current thread that we're running on because we could run this on any thread we felt like now i want to slow things down because computers are much faster than we are i'm going to say cue thread i'm going to say current thread ms sleep and what this is going to do is tell it to put the thread to sleep or stop executing for a certain number of milliseconds and i'm going to say 500 which is half of a second so it's still fairly snappy now i'm going to put something in here right now but it's not going to make sense probably till towards the end of the video let's say this delete later what this is going to do is delete this object out of memory but again it's not going to make sense just yet let's flip over to our main here now we could if we wanted to create our worker and run it on the main thread and let's go ahead and demonstrate that we're going to include q thread keyboard q worker so i'm going to just say a little bit of copy and paste action here we are going to name our main thread notice we're in our main function and we're saying the current thread is main thread now let's go ahead and do some work here so we're going to say cue info starting and then our current thread and then let's go ahead and say finished and then in here somewhere we're going to say doing stuff seems rather simple at this point right it is [Applause] now what we're going to do is we're going to show you how a non-threaded application works and we've done this before so it's going to look very familiar i'm just going to call that slot directly and what does the output look like anybody it's going to say starting doing stuff the worker is going to run so it's going to go in here and do this loop and then when it's finished it'll come back here and say finished this is not threaded let's save all and wait for it to build there we go so this is boring this is not what we want at all this is all running on the main thread you see working on main thread so this is important to remember when you get into gui programming the main thread is something you never want to lock up because look at what just happened our entire application stops and does things one at a time not fast at all we don't want that so let's fix this and turn this into a multi-threaded application now spoiler alert this will work just fine because there's no parent but we're going to demonstrate a slight issue here let's say we got a pointer so say worker let's actually turn this into a pointer again i did say i was a bit rusty [Applause] because this is a cue object we could give it a parent but if we do that we're going to get an error saying you know cannot move object to a thread that has a parent so it cannot have a parent at all so bear that in mind if you try to move something over there it's just simply not going to work now we don't want to do this because well we want to move that worker to a thread so first thing we're going to do here is a cue thread and then let's go ahead and name this i'm going to say thread and we're going to set the object name to worker thread it doesn't have to be named worker thread you can call it anything you want you can call it fuzzy kitten if you felt like it but notice we have two very distinctly different objects here we have a worker and we have a q thread and it's already saying value stores initialize and then potential memory leaks so now this thing is freaking out but don't worry we're not going to have a memory leak we're going to take this thread and this worker and we're going to smash them together or more appropriately what we're going to do is we're going to say worker dot move to thread this is the confusing bit because you'd think you'd want you know like thread move object but no we're going to say worker move to thread and then we define what thread we actually want to move it to so we're just going to simply move it to that thread notice that clang finally stopped annoying us with all those warnings because now it knows what we're doing we have two other problems first we need to start our worker when the thread starts because if we just run this as is guess what we've moved the worker but the worker doesn't know what to do it doesn't know when to start and we can't start the worker on the main thread so we need to tell the worker when the thread starts this is very very simple what we're going to do is we're going to say cue object we're going to connect we're going to connect our thread i'm gonna say q thread and we want the started and we're gonna connect that to our worker and we're going to connect that to the run slot this really is the power of cute right here is you have this ability to connect things and it's just going to automatically know what to do so when the thread is started the worker is going to call the run function which is going to kick off you guessed it this little loop right here this is going to be that hopefully light bulb moment this delete later flip back to our main what have we done we've created a pointer this is an unmanaged pointer and we're gonna have a bad time there are multiple ways of doing this we can use auto pointers but a very simple way of doing it is just saying you know what delete later when we're done with it so it's just going to get rid of it all together and we don't have to worry about it again there are better ways of doing that and we will cover those in future videos but right now if you're super worried about this little example having a memory leak just simply call this delete later it'll schedule this object for deletion inside of cute all right now the final moment of truth here what i'm going to do is i'm going to say red start so we're going to start that thread up which is going to run our worker let's go ahead and run this and see what it looks like now it seems a little confusing at first because it says starting doing and then finished wait a minute finished but our work is still going and then the worker is finally deconstructed so let's really illustrate this a little bit better notice that we are starting doing stuff on the main thread and now we're working on the worker thread so we've successfully moved it over to another thread and we've deconstructed that object i'm going to add in a little bit of code here just to illustrate and you don't really need it it's just for illustration purposes all right so we've got doing stuff and let's get rid of this guy here and we're simply going to do a loop it's almost identical code to the worker thread here and we're just going to say working and then whatever number on the current thread and we're going to sleep for 500 milliseconds so now we have two threads at the same time running and this will be a little more clear just how powerful this is run and now you can see we are working on the worker thread working on the main thread working on the main worker and it just kind of as the scheduler sees fit it's going to do its thing this is what i mean by this is how powerful threading is this simple little example we can now work on multiple threads with ease and we can clean up when we're finished 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 voidrealms 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 drop me a note 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
Info
Channel: VoidRealms
Views: 1,881
Rating: undefined out of 5
Keywords:
Id: PgLC6Bg-ryg
Channel Id: undefined
Length: 24min 15sec (1455 seconds)
Published: Wed Sep 15 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.