- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在编写一个游戏并且有一个玩家列表定义如下:
pub struct PlayerList {
by_name: HashMap<String, Arc<Mutex<Player>>>,
by_uuid: HashMap<Uuid, Arc<Mutex<Player>>>,
}
这个结构体有添加、删除、获取玩家和获取玩家数量的方法。
NetworkServer
和 Server
共享此列表如下:
NetworkServer {
...
player_list: Arc<Mutex<PlayerList>>,
...
}
Server {
...
player_list: Arc<Mutex<PlayerList>>,
...
}
这是在 Arc<Mutex>
中因为NetworkServer
在不同的线程(网络循环)中访问列表。
当玩家加入时,会为他们生成一个线程并将他们添加到 player_list 中。
虽然我正在做的唯一操作是添加到 player_list
, 我被迫使用 Arc<Mutex<Player>>
而不是更自然的 Rc<RefCell<Player>>
在HashMap
这是因为 Mutex<PlayerList>
需要它。我没有从网络线程(或任何其他线程)访问播放器,因此将它们放在 Mutex
下是没有意义的。 .只有 HashMap
需要锁定,我正在使用 Mutex<PlayerList>
进行锁定.但是 Rust 很迂腐,想要防止所有的误用。
因为我只访问 Player
在主线程中,每次都进行锁定既烦人又性能低下。有没有解决方法而不是使用 unsafe
还是什么?
这是一个例子:
use std::cell::Cell;
use std::collections::HashMap;
use std::ffi::CString;
use std::rc::Rc;
use std::sync::{Arc, Mutex};
use std::thread;
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
struct Uuid([u8; 16]);
struct Player {
pub name: String,
pub uuid: Uuid,
}
struct PlayerList {
by_name: HashMap<String, Arc<Mutex<Player>>>,
by_uuid: HashMap<Uuid, Arc<Mutex<Player>>>,
}
impl PlayerList {
fn add_player(&mut self, p: Player) {
let name = p.name.clone();
let uuid = p.uuid;
let p = Arc::new(Mutex::new(p));
self.by_name.insert(name, Arc::clone(&p));
self.by_uuid.insert(uuid, p);
}
}
struct NetworkServer {
player_list: Arc<Mutex<PlayerList>>,
}
impl NetworkServer {
fn start(&mut self) {
let player_list = Arc::clone(&self.player_list);
thread::spawn(move || {
loop {
// fake network loop
// listen for incoming connections, accept player and add them to player_list.
player_list.lock().unwrap().add_player(Player {
name: "blahblah".into(),
uuid: Uuid([0; 16]),
});
}
});
}
}
struct Server {
player_list: Arc<Mutex<PlayerList>>,
network_server: NetworkServer,
}
impl Server {
fn start(&mut self) {
self.network_server.start();
// main game loop
loop {
// I am only accessing players in this loop in this thread. (main thread)
// so Mutex for individual player is not needed although rust requires it.
}
}
}
fn main() {
let player_list = Arc::new(Mutex::new(PlayerList {
by_name: HashMap::new(),
by_uuid: HashMap::new(),
}));
let network_server = NetworkServer {
player_list: Arc::clone(&player_list),
};
let mut server = Server {
player_list,
network_server,
};
server.start();
}
最佳答案
As I'm only accessing
Players
in the main thread, locking everytime to do that is both annoying and less performant.
你的意思是,现在你只能访问 Players
在主线程中,但在以后的任何时候你可能会不小心在另一个线程中引入对它们的访问?
从语言的角度来看,如果你能得到一个值的引用,你就可以使用这个值。因此,如果多个线程引用了一个值,那么这个值应该可以安全地从多个线程使用。无法在编译时强制执行某个特定值,尽管可以访问,但实际上从未使用过。
然而,这提出了一个问题:
如果给定线程从未使用过该值,为什么该线程首先可以访问它?
在我看来,你有一个设计问题。如果您可以设法重新设计您的程序,以便只有主线程可以访问 PlayerList
, 那么您将立即能够使用 Rc<RefCell<...>>
.
例如,您可以改为让网络线程向主线程发送一条消息,宣布新玩家已连接。
目前,您正在“通过分享来交流”,您可以转向“通过交流来分享”。前者通常到处都有同步原语(例如互斥体、原子、...),并且可能面临争用/死锁问题,而后者通常有通信队列( channel )并且需要“异步”风格的编程。
关于multithreading - 不需要时强制使用 Mutex,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49782694/
我需要在一个函数内锁定一个 std::map 和两个 boost::multimaps 的操作,因为我们有线程试图访问该函数(以及映射)。 我计划使用“std::mutex mutex_var”来保护
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭11 年前。 Improve th
或不同的标题: 为什么处置获得的 Mutex 会破坏它? 我有以下代码,真正的代码在几个方法之间产生,并在这个方法休眠的地方做事: bool createdNew; u
如何测量互斥量、信号量或 futex 的延迟?我的意思是两个事件之间的延迟:解锁先前锁定的互斥体和锁定该互斥体。有两种情况:当所有线程/进程都在同一个 CPU 上时(重新调度线程需要多长时间)以及当第
我执行了以下程序,其中我创建了 100 个线程并发执行。请注意这是一个示例程序。我知道下面的程序不需要多线程,但我的目的是测试互斥量。 class ThreadPool{ public:
我有创建多个线程的代码,所有线程都尝试将信息记录在一个文件中我尝试使用互斥锁来登录文件,但是当我使用 Mutex() 和 Mutex(true or false, "name") 对象时,我得到了不同
我正在研究 Rust 示例。有这段代码: fn new(name: &str, left: usize, right: usize) -> Philosopher { Philosopher
我正在实现一个基于 std::queue 的 C++ 消息队列。 因为我需要 popers 在空队列上等待,所以我考虑使用 mutex 进行互斥,并使用 cond 在空队列上挂起线程,就像 glib
在golang中,sync.Mutex Lock和Unlock是usaul操作,但是Lock和defer Unlock的正确顺序是什么? mu.Lock() defer mu.Unlock() 或 d
在 Go 中,我们可以使用: type Data struct { lock *sync.Mutex } 或 type Data struct { lock sync.Mutex
我尝试摆脱代码中的一些 boost 依赖项,转而使用新的 C++11 功能 (Visual Studio 2013)。 在我的一个组件中,我使用了 boost::mutex与 boost::lock_
我正在使用 scoped_lock 和 mutex 来实现 BlockingQueue posted in a different SO question 的一个版本, 但在 boost 中有多个不同
我在互斥锁析构函数中遇到了上述错误。由于错误可能是由于互斥锁在销毁过程中处于锁定状态,所以我创建了一个新的互斥锁类,它继承自 boost:mutex。这是为了确保互斥锁在销毁期间解锁。但是,仍然会出现
今天写了一些代码来测试mutex的性能。 这是 boost(1.54) 版本,在 vs2010 上编译并进行了 O2 优化: boost::mutex m; auto start = boost::c
我不知道我没有做什么,但我根本无法让自己的调试器保存正在调试的应用程序的“Mutex Owned”或“Mutex Free”信息。 如果我按如下方式调用它,CDB 就可以正常工作: cdb -pn
还没有网上的例子来生动地演示这一点。在 http://en.cppreference.com/w/cpp/header/shared_mutex 看到了一个例子但目前还不清楚。有人可以帮忙吗? 最佳答
我有两个用例。 A.我想同步访问两个线程的队列。 B.我想同步两个线程对队列的访问并使用条件变量,因为其中一个线程将等待另一个线程将内容存储到队列中。 对于用例 A,我看到了使用 std::lock_
我编写了一个小型 Go 库 ( go-patan ),用于收集某些变量的运行最小值/最大值/平均值/标准偏差。我将它与等效的 Java 实现 ( patan ) 进行了比较,令我惊讶的是 Java 实
我想知道这两者之间的区别是什么 boost::timed_mutex _mutex; if(_mutex.timed_lock(boost::get_system_time() + boost::po
我正在尝试将 dyn 特征存储在 Arc>>>> 中,但是由于某种原因它不起作用 use std::sync::{Arc, Mutex}; trait A{} struct B{} impl A fo
我是一名优秀的程序员,十分优秀!