Как разделить структуру, содержащую поле Отправитель и Получатель, между потоками? - PullRequest
1 голос
/ 08 июля 2019

У меня есть структура, которая примерно выглядит следующим образом

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

...