advance/concurrency-with-threads/sync2 #734
Replies: 13 comments 23 replies
-
我看到这里了耶, 💯 |
Beta Was this translation helpful? Give feedback.
-
我用Go语言跑了一下自增的例子,大概花费了200ms,但是用rust里面的Atomic要花费4s左右,怎么差这么多哦 |
Beta Was this translation helpful? Give feedback.
-
use std::ops::Sub;
use std::sync::{Mutex, Arc};
use std::thread::{self, JoinHandle};
use std::time::Instant;
const N_TIMES: u64 = 10_000_000;
const N_THREADS: usize = 10;
fn add_n_times(n: u64, counter: Arc<Mutex<u64>>) -> JoinHandle<()> {
thread::spawn(move || {
for _ in 0..n {
let mut num = counter.lock().unwrap();
*num += 1;
}
})
}
fn main() {
let mut counter: Arc<Mutex<u64>> = Arc::new(Mutex::new(0));
let s = Instant::now();
let mut threads = Vec::with_capacity(N_THREADS);
for _ in 0..N_THREADS {
threads.push(add_n_times(N_TIMES, counter.clone()))
}
for thread in threads {
thread.join().unwrap();
}
assert_eq!(N_TIMES * N_THREADS as u64, *counter.lock().unwrap());
println!("{:?}",Instant::now().sub(s));
} 针对与第一个例子的 |
Beta Was this translation helpful? Give feedback.
-
突然就蹦出来一个变量,也不知道是啥,用方法也不说是干啥的 |
Beta Was this translation helpful? Give feedback.
-
创建线程的性能因此线程的创建耗时并不是不可忽略的 根据上下文的语境,这里应该是不应该完全忽略。 |
Beta Was this translation helpful? Give feedback.
-
这章最后一个例子用的不好, 莫明其妙的上了之前段落都没有提到过的自旋锁. |
Beta Was this translation helpful? Give feedback.
-
GPT打死不承认Atomic跨线程需要Arc,可恶 |
Beta Was this translation helpful? Give feedback.
-
Barrier是什么,为什么每一个循环都要 clone一下,这个b.wait()有什么用吗 |
Beta Was this translation helpful? Give feedback.
-
能详细说下 thread_local! 宏么? |
Beta Was this translation helpful? Give feedback.
-
对于某些没使用或者没讲过的对象能不能给个注释呀,这点可能对新手不太友好,每次一边看书,还要一边百度 |
Beta Was this translation helpful? Give feedback.
-
不科学,为什么我的使用原子类型耗时多? use std::ops::Sub;
use std::sync::{
atomic::{AtomicU64, Ordering},
Arc, Mutex,
};
use std::thread::{self, JoinHandle};
use std::time::{Duration, Instant};
const N_TIMES: u64 = 10000000;
const N_THREADS: usize = 10;
static R: AtomicU64 = AtomicU64::new(0);
fn add_n_times(n: u64) -> JoinHandle<()> {
thread::spawn(move || {
for _ in 0..n {
R.fetch_add(1, Ordering::Relaxed);
}
})
}
fn main() {
println!("use mutex: {:?}", use_mutex());
println!("use automic: {:?}", use_automic());
}
fn use_automic() -> Duration {
let s = Instant::now();
let mut threads = Vec::with_capacity(N_THREADS);
for _ in 0..N_THREADS {
threads.push(add_n_times(N_TIMES));
}
for thread in threads {
thread.join().unwrap();
}
assert_eq!(N_TIMES * N_THREADS as u64, R.load(Ordering::Relaxed));
Instant::now().sub(s)
}
fn use_mutex() -> Duration {
let s = Instant::now();
let mut threads = Vec::with_capacity(N_THREADS);
let counter: Arc<Mutex<u64>> = Arc::new(Mutex::new(0));
for _ in 0..N_THREADS {
let lock = counter.clone();
threads.push(thread::spawn(move || {
let mut num = lock.lock().unwrap();
while *num < N_TIMES * N_THREADS as u64 {
*num += 1;
}
}));
}
for thread in threads {
thread.join().unwrap();
}
assert_eq!(N_TIMES * N_THREADS as u64, *counter.lock().unwrap());
Instant::now().sub(s)
} |
Beta Was this translation helpful? Give feedback.
-
我本地跑出来的数据有点夸张了... CAS 版本 2s 左右, Mutex 版本 20s+... use std::ops::Sub;
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::{Arc, Mutex};
use std::thread::{self, JoinHandle};
use std::time::Instant;
const N_TIMES: u64 = 10000000;
const N_THREADS: usize = 10;
static R: AtomicU64 = AtomicU64::new(0);
fn add_n_times(n: u64) -> JoinHandle<()> {
thread::spawn(move || {
for _ in 0..n {
R.fetch_add(1, Ordering::Relaxed);
}
})
}
fn add_n_times_mutex(n: u64, num: Arc<Mutex<u64>>) -> JoinHandle<()> {
thread::spawn(move || {
for _ in 0..n {
let mut actual_num = num.lock().unwrap();
*actual_num += 1;
}
})
}
fn main() {
let s = Instant::now();
let mut threads = Vec::with_capacity(N_THREADS);
for _ in 0..N_THREADS {
threads.push(add_n_times(N_TIMES));
}
for thread in threads {
thread.join().unwrap();
}
assert_eq!(N_TIMES * N_THREADS as u64, R.load(Ordering::Relaxed));
println!("CAS version: {:?}", Instant::now().sub(s));
println!("================================================");
let s2 = Instant::now();
let res = Arc::new(Mutex::new(0));
let mut threads = Vec::with_capacity(N_THREADS);
for _ in 0..N_THREADS {
let temp_res = res.clone();
threads.push(add_n_times_mutex(N_TIMES, temp_res));
}
for thread in threads {
thread.join().unwrap();
}
assert_eq!(N_TIMES * N_THREADS as u64, *res.lock().unwrap());
println!("Mutex version: {:?}", Instant::now().sub(s2));
} |
Beta Was this translation helpful? Give feedback.
-
advance/concurrency-with-threads/sync2
https://course.rs/advance/concurrency-with-threads/sync2.html
Beta Was this translation helpful? Give feedback.
All reactions