multithreading - 如何在一个线程中更新并从多个线程中读取?
问题描述
我未能通过借用检查器获取此代码:
use std::sync::Arc;
use std::thread::{sleep, spawn};
use std::time::Duration;
#[derive(Debug, Clone)]
struct State {
count: u64,
not_copyable: Vec<u8>,
}
fn bar(thread_num: u8, arc_state: Arc<State>) {
let state = arc_state.clone();
loop {
sleep(Duration::from_millis(1000));
println!("thread_num: {}, state.count: {}", thread_num, state.count);
}
}
fn main() -> std::io::Result<()> {
let mut state = State {
count: 0,
not_copyable: vec![],
};
let arc_state = Arc::new(state);
for i in 0..2 {
spawn(move || {
bar(i, arc_state.clone());
});
}
loop {
sleep(Duration::from_millis(300));
state.count += 1;
}
}
我可能在尝试错误的事情。
我想要一个可以更新的(主)线程state
和许多可以读取的线程state
。
我应该如何在 Rust 中做到这一点?
我已经阅读了关于共享状态的 Rust 书,但是它使用了互斥锁,对于单个写入器/多个读取器的情况来说,这似乎过于复杂。
在 CI 中,通过大量的_Atomic
.
解决方案
原子确实是一种正确的方法,在 std (链接。您的示例需要 2 个修复。
- 在进入闭包之前必须克隆 Arc ,因此您的循环变为:
for i in 0..2 {
let arc_state = arc_state.clone();
spawn(move || { bar(i, arc_state); });
}
- 使用
AtomicU64
是相当直接的,尽管您需要明确使用指定Ordering
(Playground)的 newtype 方法:
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
use std::thread::{sleep, spawn};
use std::time::Duration;
#[derive(Debug)]
struct State {
count: AtomicU64,
not_copyable: Vec<u8>,
}
fn bar(thread_num: u8, arc_state: Arc<State>) {
let state = arc_state.clone();
loop {
sleep(Duration::from_millis(1000));
println!(
"thread_num: {}, state.count: {}",
thread_num,
state.count.load(Ordering::Relaxed)
);
}
}
fn main() -> std::io::Result<()> {
let state = State {
count: AtomicU64::new(0),
not_copyable: vec![],
};
let arc_state = Arc::new(state);
for i in 0..2 {
let arc_state = arc_state.clone();
spawn(move || {
bar(i, arc_state);
});
}
loop {
sleep(Duration::from_millis(300));
// you can't use `state` here, because it moved
arc_state.count.fetch_add(1, Ordering::Relaxed);
}
}
推荐阅读
- hibernate - 如何在未关联的实体上使用条件查询进行左外连接?
- c# - 在 WPF/C# 中,如何访问动态生成的控件的元素或以其他方式向它们添加点击事件?
- java - 如何编写一个同时使用 XML 和 JSON 的 servlet 程序?
- flutter - 文本小部件未在 StreamBuilder 内更新
- html - 在图标周围添加一个圆圈
- amazon-web-services - 如何按顺序运行多个 AWS CodePipelines?
- java - 是否有用于结束程序的函数的 java 注释?摆脱“缺少退货声明”
- sql - 使用 Oracle Query 显示所有匹配的记录
- typescript - 哪个实体应该负责通过消息代理发送消息?
- html - 以最少的重复条件渲染组件(ltr 到 rtl)中的东西?