 Hey everybody, this is Brian and welcome to the 30th Qt tutorial with C++. We're going to continue our conversation on threading and we're going to talk about the Qmutex. What is a mutex? Well, if you go through the help file, it explains that a mutex is a class that provides access serialization between threads. And they actually give you a very nice, lengthy example, and if you read through here, basically what it tells you is that bad things can happen when you use multiple threads at the same time. And I'm going to give you some very simple examples rather than making a dredge through the files. You can have what's called a deadlock where you have two threads trying to access a resource at the same time and they stop. They can't do anything. They deadlock. A good example is you have a door to a building and two people trying to walk through it at the same time, both going in opposite directions. So they're just standing there with the door open, looking at each other, going, please move. The other person is saying, please move, and neither is willing to move. They're just stuck. Another example would be a collision. Imagine you have a glass of water sitting on the table and the glass is empty. And you say to two people, okay, fill that glass. And they both try filling it at the same time. Well, the water is just going to overflow everywhere. You have too much of a good thing. So what a mutex does is it says, okay, only one of you can access this at the same time. And here's their example into number six. And then they go through this very lengthy process of explaining how threads will just mess these numbers all up and you get results you really don't want. And what you need to focus on is how to use QMutex. You understand why now? You create an instant of a mutex and you lock it. So QMutex lock, that says only this thread and this thread only can access this bit of code until you unlock it. Think of the door, the deadlock situation where you have two people trying to walk through the door at the same time. A mutex would be the guy holding the door and he will look at one of them and say, stop, this person is using the door right now. That's called a lock. And then when the other person leaves, he looks at him and says, okay, you may now pass. That's called unlocking. So we're going to actually implement this using our code. I don't like reusing code between tutorials because it really messes up people that just jump right into the middle of this. So I'm sorry. If you're coming into this tutorial, go watch the other two and you'll get the source code and I'll briefly go over it. This is our main.cpp. You see we are including mythread.h and we're just creating three instances of this thread and we're naming it each time, thread one, two, and three. And the thread class itself is actually very simple. We're just overriding run and we have a queue string or a name and the implementation when we do run, it's just very simple counting up from zero to 999. And we're going to implement a queue mutex here. So what we're going to do is make a public variable called stop. And then in our code, we're going to say, if stop, then we're just going to break out of here. Now the problem comes in. What if another thread's modifying this variable? I know it sounds crazy, but it can happen. Believe me, major, major programs have just crashed and burned because threads have collided, threads have deadlocked. So you need to make a queue mutex and then you need to lock that code. And what that does, that ensures that when this section of code is fired, only this thread is allowed to access this variable. So if another thread is trying to flip stop to true or false, while this thread's trying to read the variable, we're locking it. We're making sure that nothing bad can happen. And when you save and run it, you'll see that the program runs just as it did before. It suffers a very, very minor speed penalty because you're locking it. But that speed penalty, as you just saw, is very, very minor. But you should know there is a penalty there. Now let's actually implement this. And let's say stop equals true. So we're starting these threads and it's going to kick off a little bit and then it's going to stop it. And let's actually not start these threads. I want to really drive home the point here, what's going on. We've got two threads, believe it or not. You've been working with threads this whole time and never realized it. This main.cpp, you're creating the main program thread just by running this. And then you're creating your extra threads. And for this one, we're only going to start thread one. And then we're going to instantly stop it. Let's run this. And you see how thread running. So the thread did start, but then immediately exited. Now that really drives home a very good point. From your code, it looks like it started and stopped. And it did absolutely nothing. But when you dig into the details here, you see that it did run this line of code right here. So it ran this. But it then, however, checked to see if we should continue because we have this if stop then break. So it never ran this. Very, very interesting. Now what you could do is you could also slow the thread down. You could say sleep. Slowing a thread down gives it a bigger chunk of time. And it makes it a little more friendly because it's not constantly bothering the CPU saying, hey, here, here, here, pay attention to me. So let's actually make this a lower number here. And we'll just say one. And when you run this, same results. And I realize from the end user perspective, the output, everything looks the same. But internally, you have to understand that things are going on and things are happening and you're controlling how they work. What you're doing here is you're saying every time this iterates, you're making a mutex. And you could actually just make one mutex and then lock and unlock each time. But you're locking this code so that only this thread can modify or read this code, then you're unlocking it. That allows other threads to come in. And then you're also sleeping, which grants other threads, yet again, more time with the CPU. A lot of programmers don't do that. But when you get into, let's say, GUI programming with threading, the sleep function actually becomes very helpful because sometimes your threads run so fast your GUI cannot keep up. All right. Well, this is Brian. Thank you for watching. I hope you found this tutorial educational and entertaining.