我有一个结构大致如下
struct Node {
id: Arc<i32>,
data: Arc<Mutex<i32>>, // Actually not i32, but that is not important for this question.
rx: Receiver<()>,
tx: Sender<()>
}
我使用Receiver
中的Sender
和mpsc::channel
。
我想在多个线程之间共享。我有一个“用户”线程,其中Node
的用户在Node
上执行某些功能。这将导致一些UDP消息发送到其他计算机,并且该线程将在rx.recv()
上阻塞。在后台,我有一个或更多线程在UDP套接字上执行阻塞接收调用。当他们收到消息时,他们会更新data
结构的Node
字段,并且当后台线程注意到已经收到足够多的消息时,它将使用()
发送tx.send()
,让用户线程继续执行。
要与另一个线程共享Node
实例,我需要执行以下操作:
let node: Arc<Node> = ...
let node_for_background_thread = Arc::clone(&node);
let background_thread_handle = thread::spawn(move || {
node_for_background_thread.start_receive_loop();
});
我需要访问用户线程和后台线程中的Node
的所有字段(例如id
和data
)。这就是为什么我要在它们之间共享Node
的单个实例。但是Receiver
和Sender
都不是Sync
,因此上述内容无法编译。我知道我可以克隆Sender
并将其拥有的一个放入每个后台线程。
我看到的一种解决方案是在rx
中不包含tx
和Node
。但是然后我将丢失封装,因为Node
实例的创建者将不得不创建通道并生成后台线程。我想尽可能将它们全部封装在Node
中。
上面的代码片段是我可以手动克隆Sender
的地方。我不需要克隆Receiver
,因为我只有一个线程可以使用它。
答案 0 :(得分:0)
我在这里回答:https://stackoverflow.com/a/65354846/6070255
您可以使用标准库中的std::sync::mpsc::SyncSender。区别在于它实现了
Sync
特性,但是如果在发送消息时内部缓冲区中没有空间,它将阻塞。有关更多信息: