0Pricing
Learn Rust Coding · Pelajaran

Kanal mpsc

Mengirim antar-thread

Kanal mpsc adalah pelajaran Learn Rust Coding gratis di CoddyKit. Ini adalah pelajaran 1 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Learn Rust Coding, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Learn Rust Coding mencakup 4 pelajaran total.

Apa Itu Kanal?

Kanal adalah pipa satu arah untuk mengirim nilai dari satu thread ke thread lain. Pustaka standar Rust menyediakan std::sync::mpsc, dengan mpsc berarti banyak penghasil, satu penerima.

  • Bagian Pengirim memasukkan nilai.
  • Bagian Penerima mengambil nilai.

Kanal memungkinkan thread berkomunikasi dengan mengirim pesan, bukan berbagi memori secara langsung, sehingga banyak perlombaan data dapat dihindari.

Membuat Kanal

Panggil mpsc::channel() untuk mendapatkan tuple (Sender, Receiver). Di sini, kita mengirim satu nilai dari thread yang dibuat ke thread utama.

use std::sync::mpsc;
use std::thread;

fn main() {
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
        tx.send(42).unwrap();
    });
    let received = rx.recv().unwrap();
    println!("Got: {}", received);
}

send dan recv

tx.send(value) mengembalikan Result: operasi ini hanya gagal jika penerima telah dibuang. rx.recv() menunggu hingga suatu nilai tiba, dan mengembalikan Err saat semua pengirim sudah tidak ada.

  • send memindahkan kepemilikan nilai ke dalam kanal.
  • recv mengambil kepemilikan dari sisi lainnya.
use std::sync::mpsc;
use std::thread;

fn main() {
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
        let msg = String::from("hello from thread");
        tx.send(msg).unwrap();
    });
    let text = rx.recv().unwrap();
    println!("{}", text);
}

Kepemilikan Berpindah Melalui Kanal

Karena send menerima nilai berdasarkan nilainya, Anda tidak dapat menggunakannya setelah mengirim. Aturan saat kompilasi ini menjamin tidak ada thread yang menyimpan referensi kedaluwarsa ke data yang kini dimiliki thread lain.

Di bawah ini, mencoba mencetak msg setelah send akan menjadi kesalahan kompilasi, jadi kita hanya menggunakannya sekali.

use std::sync::mpsc;
use std::thread;

fn main() {
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
        let data = vec![1, 2, 3];
        tx.send(data).unwrap();
        // data is moved; cannot use it here
    });
    let v = rx.recv().unwrap();
    println!("Sum: {}", v.iter().sum::<i32>());
}

Melakukan Iterasi pada Penerima

Receiver mengimplementasikan IntoIterator. Perulangan pada objek ini menghasilkan setiap nilai hingga kanal ditutup (semua pengirim dibuang). Ini adalah cara idiomatis untuk menggunakan aliran pesan.

use std::sync::mpsc;
use std::thread;

fn main() {
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
        for i in 1..=3 {
            tx.send(i).unwrap();
        }
    });
    for received in rx {
        println!("Received: {}", received);
    }
}

Banyak Penghasil dengan clone

mp dalam mpsc berarti Anda dapat memiliki banyak pengirim. Gandakan Sender dan berikan salinannya kepada setiap thread. Penerima mengumpulkan semuanya hingga semua salinan dibuang.

use std::sync::mpsc;
use std::thread;

fn main() {
    let (tx, rx) = mpsc::channel();
    let tx2 = tx.clone();
    thread::spawn(move || { tx.send("from A").unwrap(); });
    thread::spawn(move || { tx2.send("from B").unwrap(); });
    for msg in rx {
        println!("{}", msg);
    }
}

Semantik Penutupan Kanal

Perulangan penerima berakhir secara otomatis saat semua pengirim dibuang. Jika bahkan satu Sender masih aktif, for msg in rx akan menunggu selamanya untuk pesan berikutnya. Selalu buang atau batasi cakupan pengirim dengan benar agar perulangan dapat selesai.

use std::sync::mpsc;
use std::thread;

fn main() {
    let (tx, rx) = mpsc::channel();
    let handle = thread::spawn(move || {
        for i in 0..3 {
            tx.send(i * 10).unwrap();
        }
        // tx dropped here, closing the channel
    });
    handle.join().unwrap();
    let total: i32 = rx.iter().sum();
    println!("Total: {}", total);
}

try_recv untuk Pembacaan Tanpa Menunggu

recv menunggu, tetapi try_recv segera mengembalikan Result. Nilainya adalah Ok(value) jika pesan siap, atau Err jika kanal kosong atau terputus. Ini berguna dalam perulangan peristiwa yang harus terus mengerjakan hal lain.

use std::sync::mpsc;
use std::thread;
use std::time::Duration;

fn main() {
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
        thread::sleep(Duration::from_millis(50));
        tx.send("ready").unwrap();
    });
    loop {
        match rx.try_recv() {
            Ok(msg) => { println!("{}", msg); break; }
            Err(_) => println!("waiting..."),
        }
        thread::sleep(Duration::from_millis(20));
    }
}

Mengirim Tipe Khusus

Tipe apa pun yang merupakan Send dapat dikirim melalui kanal, termasuk struct dan enum buatan Anda sendiri. Enum sangat cocok untuk memodelkan jenis pesan yang berbeda dalam protokol pekerja.

use std::sync::mpsc;
use std::thread;

enum Job {
    Print(String),
    Add(i32, i32),
}

fn main() {
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
        tx.send(Job::Print(String::from("hi"))).unwrap();
        tx.send(Job::Add(2, 3)).unwrap();
    });
    for job in rx {
        match job {
            Job::Print(s) => println!("print: {}", s),
            Job::Add(a, b) => println!("add: {}", a + b),
        }
    }
}

sync_channel dan Tekanan Balik

mpsc::sync_channel(n) membuat kanal terbatas dengan ukuran penyangga n. Saat penyangga penuh, send menunggu hingga ruang tersedia. Ini memberikan tekanan balik, sehingga penghasil yang cepat tidak membebani konsumen yang lambat.

  • sync_channel(0) adalah kanal pertemuan: send dan recv harus bertemu.
use std::sync::mpsc;
use std::thread;

fn main() {
    let (tx, rx) = mpsc::sync_channel(2);
    thread::spawn(move || {
        for i in 1..=4 {
            tx.send(i).unwrap();
            println!("sent {}", i);
        }
    });
    for v in rx {
        println!("got {}", v);
    }
}

Pola Pekerja Sederhana

Saluran sangat cocok untuk pola produsen/konsumen: satu utas menghasilkan item pekerjaan, utas lain mengonsumsi dan memprosesnya. Di sini, utas utama menghasilkan angka dan sebuah pekerja menguadratkan setiap angka lalu mengirimkan hasilnya melalui saluran kedua.

use std::sync::mpsc;
use std::thread;

fn main() {
    let (job_tx, job_rx) = mpsc::channel();
    let (res_tx, res_rx) = mpsc::channel();
    thread::spawn(move || {
        for n in job_rx {
            res_tx.send(n * n).unwrap();
        }
    });
    for n in 1..=4 {
        job_tx.send(n).unwrap();
    }
    drop(job_tx);
    for r in res_rx {
        println!("square: {}", r);
    }
}

Pemeriksaan Singkat

Uji pemahaman Anda tentang saluran mpsc.

Rangkuman

Anda telah mempelajari inti saluran mpsc:

  • mpsc::channel() mengembalikan pasangan (Sender, Receiver).
  • send memasukkan sebuah nilai; recv menunggu untuk mengambilnya.
  • Melakukan iterasi pada penerima mengonsumsi pesan hingga semua pengirim dilepas.
  • Gandakan Sender untuk membuat beberapa produsen.
  • try_recv tidak menunggu; sync_channel(n) menambahkan tekanan balik berbatas.

Saluran memungkinkan utas berbagi data dengan aman melalui pemindahan kepemilikan, bukan berbagi memori.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Kanal mpsc” gratis?

Ya — teks lengkap “Kanal mpsc” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Learn Rust Coding, upgrade ke CoddyKit PRO. Kursus Learn Rust Coding mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Kanal mpsc”?

Mengirim antar-thread Kamu berlatih Learn Rust Coding dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Learn Rust Coding?

Tidak diperlukan pengalaman sebelumnya. Learn Rust Coding di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 1 dari 4.

Berapa lama pelajaran “Kanal mpsc” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Learn Rust Coding ini?

Ya. Setiap pelajaran Learn Rust Coding menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Kanal mpsc
  2. Berbagi State dengan Arc/Mutex
  3. Thread Berscope
  4. Kanal Crossbeam
← Kembali ke Learn Rust Coding