Saluran mpsc
Hantar antara thread
Saluran mpsc ialah pelajaran Belajar Pengaturcaraan Rust percuma di CoddyKit. Ini ialah pelajaran 1 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Belajar Pengaturcaraan Rust, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Belajar Pengaturcaraan Rust merangkumi sejumlah 4 pelajaran.
Apakah Itu Saluran?
Saluran ialah paip sehala untuk menghantar nilai daripada satu bebenang kepada bebenang yang lain. Pustaka standard Rust menyediakan std::sync::mpsc, yang bermaksud multiple producer, single consumer (berbilang penghasil, satu pengguna).
- Bahagian Sender menolak nilai masuk.
- Bahagian Receiver menarik nilai keluar.
Saluran membolehkan bebenang berkomunikasi dengan menghantar mesej, bukannya berkongsi memori secara langsung, sekali gus mengelakkan banyak perlumbaan data.
Mencipta Saluran
Panggil mpsc::channel() untuk mendapatkan tuple (Sender, Receiver). Di sini, kita menghantar satu nilai daripada bebenang yang dijana kembali kepada bebenang 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: ia hanya gagal jika penerima telah digugurkan. rx.recv() menyekat sehingga nilai tiba, lalu mengembalikan Err apabila semua penghasil sudah tiada.
sendmemindahkan pemilikan nilai ke dalam saluran.recvmengambil pemilikan keluar di sebelah yang satu lagi.
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);
}Pemilikan Bergerak Melalui Saluran
Oleh sebab send menerima nilai mengikut nilai, anda tidak boleh menggunakannya selepas menghantar. Peraturan semasa kompilasi ini menjamin bahawa tiada bebenang menyimpan rujukan lapuk kepada data yang kini dimiliki oleh bebenang lain.
Di bawah, cubaan mencetak msg selepas send akan menjadi ralat 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 Lelaran pada Receiver
Receiver melaksanakan IntoIterator. Lelaran ke atasnya menghasilkan setiap nilai sehingga saluran ditutup (semua penghasil digugurkan). Ini ialah cara idiomatik untuk menggunakan aliran mesej.
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);
}
}Berbilang Penghasil dengan clone
mp dalam mpsc bermaksud anda boleh mempunyai banyak penghasil. Clone Sender dan berikan satu salinan kepada setiap bebenang. Penerima mengumpulkan semuanya sehingga setiap klon digugurkan.
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 Saluran
Gelung penerima tamat secara automatik apabila semua penghasil digugurkan. Jika walaupun satu Sender masih hidup, for msg in rx akan menyekat selama-lamanya sambil menunggu lebih banyak nilai. Sentiasa gugurkan atau skopkan penghasil dengan betul supaya gelung dapat tamat.
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 Bacaan Tanpa Sekatan
recv menyekat, tetapi try_recv mengembalikan hasil serta-merta dengan Result. Ia memberikan Ok(value) jika mesej sudah tersedia, atau Err jika saluran kosong atau terputus. Ini berguna dalam gelung peristiwa yang perlu terus melakukan kerja 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));
}
}Menghantar Jenis Tersuai
Mana-mana jenis yang merupakan Send boleh bergerak melalui saluran, termasuk struct dan enum anda sendiri. Enum sangat sesuai untuk memodelkan jenis mesej yang berbeza 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) mencipta saluran berhad dengan saiz penimbal n. Apabila penimbal penuh, send menyekat sehingga ruang tersedia semula. Ini memberikan tekanan balik, lalu menghalang penghasil pantas daripada membebankan pengguna yang perlahan.
sync_channel(0)ialah saluran pertemuan: send dan recv mesti berlaku serentak.
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);
}
}Corak Pekerja Ringkas
Saluran sangat sesuai untuk corak pengeluar/pengguna: satu utas menghasilkan item kerja, manakala utas lain menerima dan memprosesnya. Di sini, utas utama menghasilkan nombor dan utas pekerja mengkuasaduakan setiap nombor sebelum melaporkannya semula 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);
}
}Semakan Pantas
Uji pemahaman anda tentang saluran mpsc.
Ulang Kaji
Anda telah mempelajari asas saluran mpsc:
mpsc::channel()mengembalikan pasangan(Sender, Receiver).sendmemindahkan nilai masuk;recvmenunggu secara menyekat untuk mengambilnya keluar.- Pengulangan pada penerima menggunakan semua mesej sehingga semua pengirim dilepaskan.
- Gandakan
Senderuntuk menggunakan beberapa pengeluar. try_recvtidak menyekat;sync_channel(n)menambah tekanan balik yang mempunyai had.
Saluran membolehkan utas berkongsi data dengan selamat dengan memindahkan pemilikan, bukannya berkongsi memori.
Pelajari Rust dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 39
- Pelajaran
- 144
Soalan Lazim
Adakah pelajaran “Saluran mpsc” percuma?
Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Belajar Pengaturcaraan Rust, termasuk “Saluran mpsc”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Belajar Pengaturcaraan Rust merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Saluran mpsc”?
Hantar antara thread Anda berlatih Belajar Pengaturcaraan Rust menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Belajar Pengaturcaraan Rust?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Belajar Pengaturcaraan Rust di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 1 daripada 4.
Berapa lamakah pelajaran “Saluran mpsc” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Belajar Pengaturcaraan Rust ini?
Ya. Setiap pelajaran Belajar Pengaturcaraan Rust menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.