-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2a29ff9
commit 046d865
Showing
5 changed files
with
75 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# Mutexes | ||
|
||
In the previous section, atomics were explained and when atomicity was required was mentioned. When it comes to shared data, atomicity may not always be a solution or may be insufficient. For example, if you are working with a data type that is not atomically supported, or if your algorithm needs safe execution, atomic types will not be enough to solve your problem. | ||
|
||
For example: | ||
```jule | ||
use std::sync::{WaitGroup} | ||
static mut n = 0 | ||
fn add_to_n(mut wg: &WaitGroup) { | ||
defer { wg.done() } | ||
outln("incrementing") | ||
n++ | ||
outln("incremented") | ||
} | ||
fn main() { | ||
let mut wg = WaitGroup.new() | ||
let mut j = 0 | ||
for j < 1000000; j++ { | ||
wg.add(1) | ||
co add_to_n(wg) | ||
} | ||
wg.wait() | ||
outln(n) | ||
} | ||
``` | ||
|
||
In the above code, not only the value of `n` variables is manipulated, but some functions are also called. Atomic types are not a good approach in such cases. | ||
|
||
To solve this problem we can use a mutex. Mutexes are locking mechanisms that allow you to do this. They can only be locked by a single thread at a time. If a locking attempt is made by a different thread when they are locked, the execution of the thread will be stopped until the locking thread releases the lock. | ||
|
||
For example: | ||
|
||
```jule | ||
use std::sync::{WaitGroup, Mutex} // [!code ++] | ||
static mut n = 0 | ||
static mtx = Mutex.new() // [!code ++] | ||
fn add_to_n(mut wg: &WaitGroup) { | ||
defer { wg.done() } | ||
mtx.lock() // [!code ++] | ||
outln("incrementing") | ||
n++ | ||
outln("incremented") | ||
mtx.unlock() // [!code ++] | ||
} | ||
fn main() { | ||
let mut wg = WaitGroup.new() | ||
let mut j = 0 | ||
for j < 1000000; j++ { | ||
wg.add(1) | ||
co add_to_n(wg) | ||
} | ||
wg.wait() | ||
outln(n) | ||
} | ||
``` | ||
|
||
In the code above, synchronization between threads is achieved by using mutex. Thanks to Mutex, only one thread can continue executing the relevant function at a time, and the others are waiting to take over the lock. This means that another thread cannot continue execution until one thread has completely completed its execution. In this way, race condition is prevented. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters