Skip to content

Commit 22754c3

Browse files
authored
Merge pull request #6 from JadeCara/jade/data_race
Jade/data race
2 parents 7168748 + 68f76ec commit 22754c3

File tree

3 files changed

+157
-0
lines changed

3 files changed

+157
-0
lines changed

module2/data_race/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[package]
2+
name = "data_race"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]

module2/data_race/Makefile

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
SHELL := /bin/bash
2+
.PHONY: help
3+
4+
help:
5+
@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
6+
7+
clean: ## Clean the project using cargo
8+
cargo clean
9+
10+
build: ## Build the project using cargo
11+
cargo build
12+
13+
run: ## Run the project using cargo
14+
cargo run
15+
16+
test: ## Run the tests using cargo
17+
cargo test
18+
19+
lint: ## Run the linter using cargo
20+
@rustup component add clippy 2> /dev/null
21+
cargo clippy
22+
23+
format: ## Format the code using cargo
24+
@rustup component add rustfmt 2> /dev/null
25+
cargo fmt
26+
27+
release:
28+
cargo build --release
29+
30+
all: format lint test run
31+
32+
bump: ## Bump the version of the project
33+
@echo "Current version is $(shell cargo pkgid | cut -d# -f2)"
34+
@read -p "Enter the new version: " version; \
35+
updated_version=$$(cargo pkgid | cut -d# -f2 | sed "s/$(shell cargo pkgid | cut -d# -f2)/$$version/"); \
36+
sed -i -E "s/^version = .*/version = \"$$updated_version\"/" Cargo.toml
37+
@echo "Version bumped to $$(cargo pkgid | cut -d# -f2)"
38+
rm Cargo.toml-e

module2/data_race/src/main.rs

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// Mutex that protects the data vector, and then we spawn three threads
2+
//that each acquire a lock on the mutex and modify an element of the vector.
3+
// https://doc.rust-lang.org/std/sync/struct.Mutex.html
4+
5+
use std::sync::{Arc, Condvar, Mutex, RwLock};
6+
use std::thread;
7+
8+
fn using_mutex() {
9+
println!("Mutex Example");
10+
let data = Arc::new(Mutex::new(vec![1, 2, 3]));
11+
12+
let handles: Vec<_> = (0..3)
13+
.map(|i| {
14+
let data = Arc::clone(&data);
15+
thread::spawn(move || {
16+
let mut data = data.lock().unwrap();
17+
data[i] += 1;
18+
println!("{:?}", data);
19+
})
20+
})
21+
.collect();
22+
23+
for handle in handles {
24+
handle.join().unwrap();
25+
}
26+
27+
let data = data.lock().unwrap();
28+
println!("Final data: {:?}", *data);
29+
}
30+
31+
fn using_rwlock() {
32+
println!("RwLock Example");
33+
// Create an RwLock protecting a vector
34+
let data = Arc::new(RwLock::new(vec![1, 2, 3]));
35+
36+
// Spawn three threads that each acquire a write lock on the RwLock and modify an element of the vector
37+
let handles: Vec<_> = (0..3)
38+
.map(|i| {
39+
let data = Arc::clone(&data);
40+
thread::spawn(move || {
41+
let mut data = data.write().unwrap();
42+
data[i] += 1;
43+
println!("Thread {}: {:?}", i, *data);
44+
})
45+
})
46+
.collect();
47+
48+
// Wait for all threads to finish
49+
for handle in handles {
50+
handle.join().unwrap();
51+
}
52+
53+
// Acquire a read lock to print the final state of the vector
54+
let data = data.read().unwrap();
55+
56+
println!("Final data: {:?}", *data);
57+
}
58+
59+
fn using_condvar() {
60+
println!("Condvar Example");
61+
let data = Arc::new((Mutex::new(vec![1, 2, 3]), Condvar::new()));
62+
let mut handles = vec![];
63+
64+
for i in 0..3 {
65+
let data = Arc::clone(&data);
66+
let handle = thread::spawn(move || {
67+
let (lock, cvar) = &*data;
68+
let mut data = lock.lock().unwrap();
69+
data[i] += 1;
70+
println!("Thread {}: {:?}", i, *data);
71+
cvar.notify_one();
72+
});
73+
handles.push(handle);
74+
}
75+
76+
for handle in handles {
77+
handle.join().unwrap();
78+
}
79+
80+
let (lock, cvar) = &*data;
81+
let mut data = lock.lock().unwrap();
82+
while data.iter().any(|&x| x == 1) {
83+
data = cvar.wait(data).unwrap();
84+
}
85+
86+
println!("Final data: {:?}", *data);
87+
}
88+
89+
fn main() {
90+
using_mutex();
91+
using_rwlock();
92+
using_condvar();
93+
}
94+
95+
/*
96+
97+
// This code will not compile because the borrow checker will prevent it.
98+
use std::thread;
99+
100+
fn main() {
101+
let mut data = vec![1, 2, 3];
102+
103+
for i in 0..3 {
104+
// Try to capture a mutable reference in multiple threads
105+
// This will fail to compile!
106+
thread::spawn(move || {
107+
data[i] += 1;
108+
});
109+
}
110+
111+
// No data race can occur, this will not compile.
112+
}
113+
*/

0 commit comments

Comments
 (0)