7个版本
0.4.0 |
|
---|---|
0.3.3 | 2023年10月30日 |
0.3.2 | 2023年9月11日 |
0.3.1 | 2022年8月27日 |
0.1.0 | 2021年3月4日 |
#166 in 嵌入式开发
每月37次下载
在2个crate中使用(通过memac)
24KB
495 行
Rust中no_std环境的同步工具
MCS锁
MCS锁是一种公平且可扩展的互斥锁。它可以作为std::sync::Mutex使用。
use synctools::mcs;
use std::sync::Arc;
use std::vec::Vec;
const NUM_LOOP: usize = 10000000;
const NUM_THREADS: usize = 4;
fn main() {
// create a MCSLock object
let n = Arc::new(mcs::MCSLock::new(0));
let mut v = Vec::new();
for _ in 0..NUM_THREADS {
let n0 = n.clone();
let t = std::thread::spawn(move || {
let mut node = mcs::MCSNode::new();
for _ in 0..NUM_LOOP {
// lock and acquire the reference
let mut r = n0.lock(&mut node);
// increment atomically
*r += 1;
}
});
v.push(t);
}
for t in v {
t.join().unwrap();
}
let mut node = mcs::MCSNode::new();
let r = n.lock(&mut node);
assert_eq!(NUM_LOOP * NUM_THREADS, *r);
}
读写锁
基于自旋锁的读写锁可以用来作为std::sync::RwLock。
use synctools::rwlock;
use std::sync::Arc;
use std::vec::Vec;
const NUM_LOOP: usize = 10000000;
const NUM_THREADS: usize = 4;
fn main() {
// create a RwLock object
let n = Arc::new(rwlock::RwLock::new(0));
let mut v = Vec::new();
// reader
for _ in 0..(NUM_THREADS - 1) {
let n0 = n.clone();
let t = std::thread::spawn(move || {
for _ in 0..NUM_LOOP {
// read lock
let r = n0.read();
assert_eq!(*r, 0);
}
});
v.push(t);
}
// writer
let n0 = n.clone();
let wr = std::thread::spawn(move || {
for _ in 0..NUM_LOOP {
{
// write lock
let mut r = n0.write();
*r += 1;
*r -= 1;
}
}
});
v.push(wr);
for t in v {
t.join().unwrap();
}
}
无锁栈(仅限AArch64)
无锁栈是一个并发数据结构。这只能在AArch64和nightly版本中使用,因为它在内部使用了内联汇编中的LL/SC指令。
use synctools::lfstack;
use std::sync::Arc;
use std::vec::Vec;
const NUM_LOOP: usize = 10000000;
const NUM_THREADS: usize = 4;
fn main() {
// create a stack
let mut stack = Arc::new(lfstack::LFStack::<usize>::new());
let mut v = Vec::new();
for i in 0..NUM_THREADS {
let mut stack0 = stack.clone();
let t = std::thread::spawn(move || {
if i & 1 == 0 { // even thread
for j in 0..NUM_LOOP {
let k = i * NUM_LOOP + j;
// push k to the stack
stack0.get_mut().push(k);
}
} else { // odd thread
for _ in 0..NUM_LOOP {
loop {
// pop from the stack
if let Some(k) = stack0.get_mut().pop() {
break;
}
}
}
}
});
v.push(t);
}
for t in v {
t.join().unwrap();
}
assert_eq!(stack.get_mut().pop(), None);
}
如何测试
运行
$ cargo +nightly test
对于AArch64,或者
$ cargo +nightly test --no-default-features
对于非AArch64环境。
依赖项
~0–24MB
~334K SLoC