Message.
Passing is not the only way we can communicate.
We can use new taxes.
A mutex is a shortened name for mutual exclusion and only allows one thread access to some data at any
given time.
To allow only one thread access to the data, there is a lock.
Alok is a part of the mutex data structure that keeps track of who currently has exclusive access to
the data.
When the thread says, Hey, I want that data.
It must ask for the mutex as lock, and then once the lock is acquired, nobody else can use that data
until the lock is given back.
There are two rules to follow.
You must acquire the lock before using the data.
And when you're done with the data that the mutex is guarding, you must give the lock back so that
it is unlocked for every other thread to be able to obtain access.
So now let's see how we can use mutex and threads for the example.
Remember that arc is handy for sharing things across threads and that a mutex is handy for mutating
data that is shared across threads.
So the first thing we want to do is bring.
The art smart pointer and a mutex into scope.
So we'll bring ark and mutex into scope.
Now we're going to create a counter and we'll make it an arc that contains.
Mutex in the value.
Is going to be zero.
And now we're going to create a handle's vector.
That's going to store all the join handles we create.
So now we're going to have a little loop and we don't care about any of the values inside.
So we'll say four 0 to 10 and actually I'll make it eight.
We'll say let counter equals arc clone.
And then a reference to our counter variable.
And now we'll say let handle equal threats bond and we'll say let mutable num equals counter.
Now we have to lock it to gain access to the counter and we want to unwrap the value inside.
The reference, the number and add one to it.
And that's how we're going to get our calendar to go from 0 to 1, two, three, four, five, six,
seven, eight.
And once we're done with that, obviously we need to push.
Our handle into our vector.
For now for us to join our threads.
So for handle and handles, handle, dot, join and then it respects it expects a result.
And now we can print out.
Counter Dot.
Lock, dot and wrap.
That way we can see our final count.
And if we run this, we see eight is printed out.
Now that we see kind of how mutex is work in a sense, let's see what would happen if we created a.
Headlock.
So now we'll say let mutable num two equals to counter dot lock
unwrap it.
So now here we're saying, hey, I want we're giving the lock to num.
But now we have number two also requesting that lock.
And what this is going to do is it's going to prevent.
This.
From ever being able to execute.
Now.
Plus one because we're going to get stuck here as number two is waiting for the lock.
But Num holds it, but NUM cannot give it up because it cannot finish running its execution.
So we're just never going to be able to finish running this.
And this is a really simple example of what a deadlock is.
But it really demonstrates the purpose of a mutex and that data is unacceptable to other threads.
While one thread contains a lock.
And.
So we'll we'll close this out and then obviously get rid of that to remove our deadlock.
And again, we'll just run it.
And what's happening is for every thread that we create.
It's getting the lock.
It's adding one.
It gives up the lock.
Ear lock is given up, and now the next thread gets it.
And then the lock gives up.
And it does this eight times for the eight threads that we are creating.
So.
That's really all there is to it.
To concurrency.
There are a couple of crates available to us called Cross Beam and ray on.
And I encourage you to check those out now that you have a really good understanding of how concurrency
works in rust, and you can check those crates out and see how they try to help simplify creating concurrent
programs.
But now that you have a great understanding of how concurrency works, let's continue on into asynchronous
programming.