Почему эти темы прерываются до окончания своей работы?

Учитывая следующий код:

use std::sync::mpsc::{channel, Sender, Receiver};
use std::thread;

fn transceiver(
    tx: Sender<u32>,   tx_string: &str,
    rx: Receiver<u32>, rx_string: &str,
) {
    let message_count = 3;
    for message in 0..message_count {
        println!("message {}: {}", message, tx_string);
        tx.send(message).unwrap();
        println!("message {}: {}", rx.recv().unwrap(), rx_string);
    }
}

fn main() {

    let (atx, arx) = channel();
    let (btx, brx) = channel();

    thread::spawn(move || {
        transceiver(atx, "A --> B", brx, "A <-- B");
    });

    thread::spawn(move || {
        transceiver(btx, "B --> A", arx, "B <-- A");
    });
}

Я не получаю выходной. Я должен был добавить задержку в конце main:

std::old_io::timer::sleep(std::time::duration::Duration::seconds(1));

После этого я получаю этот вывод:

message 0: B --> A
message 0: A --> B
message 0: A <-- B
message 0: B <-- A
message 1: B --> A
message 1: A --> B
message 1: A <-- B
message 2: A --> B
message 1: B <-- A
message 2: B --> A
message 2: B <-- A
message 2: A <-- B

Док говорит, что эти темы должны пережить своих родителей, но здесь кажется, что они умирают, как только родитель (в данном случае, main), умирает.

1 ответ

Решение

Док говорит, что эти темы должны пережить своих родителей, но здесь кажется, что они умирают, как только родитель (в данном случае, main), умирает.

Это не относится к основному потоку; программа заканчивается после завершения основного потока.

То, что вы хотите сделать, это дать основному потоку дождаться завершения других потоков, то есть вы хотите "присоединить" дочерний поток к основному потоку. Увидеть join метод для этого.

let (atx, arx) = channel();
let (btx, brx) = channel();

let guard0 = thread::scoped(move || {
    transceiver(atx, "A --> B", brx, "A <-- B");
});

let guard1 = thread::scoped(move || {
    transceiver(btx, "B --> A", arx, "B <-- A");
});

guard0.join();
guard1.join();

Обратите внимание, что звонки на join неявные, когда JoinGuard падает, но они сделаны здесь явно для иллюстрации.

Другие вопросы по тегам