У меня есть структура, которая примерно выглядит следующим образом
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
, поскольку у меня будет только один поток, который будет его использовать.