Memindahkan Data ke Thread
Gunakan closure move dengan benar.
Memindahkan Data ke Thread adalah pelajaran Learn Rust Coding gratis di CoddyKit. Ini adalah pelajaran 2 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.
Penutupan Menangkap Lingkungan
Penutupan yang diberikan kepada thread::spawn dapat menggunakan variabel dari lingkup di sekitarnya. Secara bawaan, Rust meminjam variabel tersebut.
Namun, utas yang dibuat mungkin hidup lebih lama daripada fungsi yang membuatnya, sehingga peminjaman biasa tidak aman. Rust menolaknya saat kompilasi.
Masalah Peminjaman
Jika sebuah utas meminjam variabel lokal, kompiler tidak dapat membuktikan bahwa variabel tersebut hidup cukup lama. Utas itu mungkin terus berjalan setelah variabel dihapus.
Kode di bawah tidak dapat dikompilasi karena penutupan hanya meminjam data.
use std::thread;
fn main() {
let data = vec![1, 2, 3];
// ERROR: closure may outlive `data`
let h = thread::spawn(|| {
println!("{:?}", data);
});
h.join().unwrap();
}Kata Kunci move
Menambahkan move sebelum penutupan memaksanya mengambil kepemilikan variabel yang ditangkap. Variabel tersebut dipindahkan ke dalam utas.
Sekarang utas memiliki data tersebut, sehingga data dijamin tetap valid selama masa hidup utas.
use std::thread;
fn main() {
let data = vec![1, 2, 3];
let h = thread::spawn(move || {
println!("{:?}", data);
});
h.join().unwrap();
}Kepemilikan Berpindah Keluar
Setelah sebuah nilai dipindahkan ke dalam utas, lingkup asal tidak dapat lagi menggunakannya. Kepemilikannya telah berpindah.
Mencoba menggunakan data di main setelah pemindahan akan menjadi kesalahan kompilasi. Kini utas tersebut adalah satu-satunya pemilik.
use std::thread;
fn main() {
let data = vec![1, 2, 3];
let h = thread::spawn(move || println!("{:?}", data));
// println!("{:?}", data); // ERROR: value moved
h.join().unwrap();
}Memindahkan Tipe Copy
Tipe yang menerapkan Copy, seperti bilangan bulat, disalin alih-alih dipindahkan. Penutupan mendapatkan salinannya sendiri.
Jadi, setelah penutupan move menangkap sebuah angka, Anda masih dapat menggunakan angka asli di main.
use std::thread;
fn main() {
let n = 42;
let h = thread::spawn(move || {
println!("thread sees {}", n);
});
println!("main still sees {}", n);
h.join().unwrap();
}Send: Aman untuk Dipindahkan
Sebuah tipe hanya dapat dipindahkan ke utas lain jika menerapkan sifat Send. Send berarti tipe tersebut aman untuk dipindahkan kepemilikannya antarutas.
Sebagian besar tipe otomatis merupakan Send. Beberapa tipe, seperti Rc, bukan Send, sehingga kompiler akan menolak pemindahannya.
Rc Bukan Send
Rc adalah penghitung referensi untuk satu utas. Penghitungnya tidak dilindungi dari pembaruan bersamaan, sehingga bukan Send.
Mencoba memindahkan Rc ke dalam utas gagal dikompilasi. Pada pelajaran berikutnya, Anda akan menggunakan Arc sebagai gantinya.
use std::rc::Rc;
use std::thread;
fn main() {
let r = Rc::new(5);
// ERROR: `Rc<i32>` cannot be sent between threads safely
let h = thread::spawn(move || println!("{}", r));
h.join().unwrap();
}Memindahkan Beberapa Nilai
Satu penutupan move dapat menangkap beberapa variabel sekaligus. Semua variabel tersebut dipindahkan ke dalam utas.
Ini berguna ketika pekerja memerlukan masukan dan label.
use std::thread;
fn main() {
let label = String::from("sum");
let nums = vec![1, 2, 3, 4];
let h = thread::spawn(move || {
let total: i32 = nums.iter().sum();
println!("{} = {}", label, total);
});
h.join().unwrap();
}Mengkloning Sebelum Memindahkan
Jika utas dan fungsi utama sama-sama memerlukan sebuah nilai, kloninglah terlebih dahulu. Berikan satu klon kepada utas dan simpan klon lainnya.
Kloning menyalin data, sehingga setiap sisi memiliki nilai independen.
use std::thread;
fn main() {
let original = String::from("hello");
let for_thread = original.clone();
let h = thread::spawn(move || println!("thread: {}", for_thread));
println!("main: {}", original);
h.join().unwrap();
}Mengembalikan Data yang Dipindahkan
Utas yang memiliki data yang dipindahkan dapat mengembalikannya, sehingga kepemilikannya kembali kepada induk melalui join.
Pola ini memindahkan data ke dalam, memprosesnya, lalu memindahkan hasilnya ke luar.
use std::thread;
fn main() {
let mut v = vec![3, 1, 2];
let h = thread::spawn(move || {
v.sort();
v
});
let sorted = h.join().unwrap();
println!("{:?}", sorted);
}Mengapa move Diperlukan
Tanpa move, pemeriksa peminjaman menganggap bahwa penutupan melakukan peminjaman. Karena utas yang dibuat tidak memiliki batas masa hidup tetap yang terikat pada pemanggil, peminjaman tidak aman.
Kata kunci move mengubah peminjaman menjadi pemindahan kepemilikan, sehingga memenuhi persyaratan 'static milik spawn.
Pemeriksaan Singkat
Uji pemahaman Anda tentang memindahkan data ke dalam utas.
Ringkasan
Anda telah mempelajari bahwa closure thread harus memiliki data yang digunakannya, yang dicapai dengan kata kunci move.
Memindahkan data berarti memindahkan kepemilikan, sedangkan tipe Copy akan disalin. Trait Send menandai data yang aman untuk dipindahkan, dan Rc bukanlah Send.
Selanjutnya, Anda akan berbagi data antarthread menggunakan Arc dan Mutex.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Memindahkan Data ke Thread” gratis?
Ya — teks lengkap “Memindahkan Data ke Thread” 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 “Memindahkan Data ke Thread”?
Gunakan closure move dengan benar. 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 2 dari 4.
Berapa lama pelajaran “Memindahkan Data ke Thread” 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
- Membuat Thread
- Memindahkan Data ke Thread
- Berbagi dengan Arc dan Mutex
- Menggabungkan dan Mengumpulkan Hasil