0Pricing
Learn Rust Coding · Pelajaran

Konkurensi Tanpa Rasa Takut dengan Thread

Pelajari primitif Rust untuk pemrograman konkuren, termasuk thread dan pengiriman pesan, sambil memastikan bebas dari perlombaan data.

Konkurensi Tanpa Rasa Takut dengan Thread adalah pelajaran Learn Rust Coding gratis di CoddyKit. Ini adalah pelajaran 3 dari 3. 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 3 pelajaran total.

Pengantar Konkurensi

Selamat datang di Konkurensi Tanpa Rasa Khawatir dengan Thread! Dalam pelajaran ini, kita akan mempelajari cara membuat program Rust Anda melakukan beberapa hal sekaligus.

Konkurensi berarti menjalankan beberapa komputasi seolah-olah pada saat yang sama. Konkurensi sangat penting untuk aplikasi yang responsif dan pemanfaatan prosesor modern dengan banyak inti.

  • Thread adalah unit eksekusi ringan di dalam program.
  • Setiap thread dapat menjalankan bagian kode yang terpisah.
  • Sistem kepemilikan Rust membantu mencegah bug konkurensi yang umum.

Membuat Thread Pertama Anda

Rust menyediakan std::thread::spawn untuk membuat thread baru. Anda memberikan closure (fungsi anonim) yang berisi kode yang harus dijalankan oleh thread baru tersebut.

Cobalah menjalankan contoh ini untuk melihat thread bekerja:

use std::thread;
use std::time::Duration;

fn main() {
  println!("Hello from the main thread!");

  thread::spawn(|| {
    for i in 1..=5 {
      println!("Hi number {} from the spawned thread!", i);
      thread::sleep(Duration::from_millis(1));
    }
  });

  for i in 1..=3 {
    println!("Hi number {} from the main thread!", i);
    thread::sleep(Duration::from_millis(1));
  }
}

Menunggu Thread dengan `join`

Pada contoh sebelumnya, thread yang dibuat mungkin belum selesai sebelum thread utama keluar. Ini karena thread utama secara bawaan tidak menunggu thread yang dibuat.

Untuk memastikan thread yang dibuat menyelesaikan pekerjaannya, kita menggunakan metode join() pada JoinHandle-nya. Ini menahan thread saat ini hingga thread yang digabungkan selesai.

use std::thread;
use std::time::Duration;

fn main() {
  let handle = thread::spawn(|| {
    for i in 1..=5 {
      println!("Thread: {}", i);
      thread::sleep(Duration::from_millis(1));
    }
  });

  for i in 1..=3 {
    println!("Main: {}", i);
    thread::sleep(Duration::from_millis(1));
  }

  handle.join().unwrap(); // Wait for the spawned thread to finish
  println!("Spawned thread has finished!");
}

Memindahkan Data ke dalam Thread

Saat Anda menggunakan variabel dari lingkungan di dalam closure spawn, aturan kepemilikan Rust mulai berlaku. Secara bawaan, closure mencoba meminjam variabel.

Jika thread yang dibuat tetap hidup setelah cakupan thread utama tempat variabel tersebut didefinisikan berakhir, hal ini dapat menyebabkan referensi yang menggantung. Untuk memperbaikinya, gunakan kata kunci move sebelum parameter closure.

  • move memaksa closure mengambil kepemilikan variabel yang ditangkapnya.
  • Ini memastikan data tetap valid sepanjang masa hidup thread baru.
use std::thread;

fn main() {
  let data = String::from("Hello from outer scope");

  let handle = thread::spawn(move || { // Use 'move' to take ownership of 'data'
    println!("Data in thread: {}", data);
  });

  handle.join().unwrap();
  // println!("Data after thread: {}", data); // This would cause a compile error!
  println!("Main thread finished.");
}

Berkomunikasi dengan Pengiriman Pesan

Meskipun berbagi data secara langsung antarthread (keadaan bersama) dimungkinkan di Rust, hal ini memerlukan sinkronisasi yang cermat (misalnya dengan Mutex dan Arc, yang dibahas dalam pelajaran lain).

Pendekatan yang lebih aman dan sering kali lebih sederhana untuk konkurensi adalah pengiriman pesan. Thread berkomunikasi dengan saling mengirim pesan, sehingga menghindari akses langsung ke memori bersama.

  • Satu thread mengirim data.
  • Thread lain menerima data.
  • Pustaka standar Rust menyediakan std::sync::mpsc untuk hal ini.

Menyiapkan Kanal `mpsc`

std::sync::mpsc adalah singkatan dari Multiple Producer, Single Consumer. Artinya, banyak thread dapat mengirim pesan, tetapi hanya satu thread yang dapat menerimanya.

Untuk membuat kanal, Anda memanggil mpsc::channel(). Fungsi ini mengembalikan tuple yang berisi:

  • Pengirim (tx): Digunakan untuk mengirim pesan.
  • Penerima (rx): Digunakan untuk menerima pesan.

Mari kita lihat cara membuat kanal dan mengirim pesan sederhana.

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

fn main() {
  // Create a new channel
  let (tx, rx) = mpsc::channel();

  thread::spawn(move || {
    let val = String::from("hi");
    tx.send(val).unwrap(); // Send the message
    // println!("val is {}", val); // Error: val moved to tx.send()
  });

  // Receive the message in the main thread
  let received = rx.recv().unwrap();
  println!("Got: {}", received);
}

Mengirim Beberapa Pesan

Anda dapat mengirim beberapa pesan melalui kanal yang sama. Receiver memiliki metode untuk menanganinya:

  • rx.recv(): Menahan thread saat ini hingga pesan diterima. Mengembalikan Result.
  • rx.try_recv(): Tidak menahan thread. Segera mengembalikan Result, yang berisi pesan atau galat jika tidak ada pesan yang tersedia.
  • Anda juga dapat melakukan iterasi langsung pada Receiver untuk mendapatkan pesan hingga pengirim menutup kanal.
use std::sync::mpsc;
use std::thread;
use std::time::Duration;

fn main() {
  let (tx, rx) = mpsc::channel();

  thread::spawn(move || {
    let msgs = vec!["hi", "from", "the", "thread"];
    for msg in msgs {
      tx.send(String::from(msg)).unwrap();
      thread::sleep(Duration::from_millis(10));
    }
  });

  // Iterate over the receiver to get all messages
  for received in rx {
    println!("Got: {}", received);
  }
  println!("All messages received!");
}

Banyak Pengirim, Satu Penerima

'MP' dalam mpsc berarti Multiple Producers. Anda dapat menggandakan Sender agar beberapa thread dapat mengirim pesan ke Receiver yang sama.

Setiap Sender yang digandakan berbagi akses ke kanal yang sama, sehingga memungkinkan pengiriman pesan secara bersamaan dari thread yang berbeda.

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

fn main() {
  let (tx, rx) = mpsc::channel();

  let tx1 = tx.clone(); // Clone the sender for another thread
  thread::spawn(move || {
    tx1.send(String::from("hello from tx1")).unwrap();
  });

  thread::spawn(move || {
    tx.send(String::from("hello from tx2")).unwrap();
  });

  // Collect all messages
  let mut received_messages: Vec<String> = vec![];
  for received in rx {
    received_messages.push(received);
    if received_messages.len() == 2 { break; } // Assuming 2 messages for this example
  }
  println!("Received: {:?}", received_messages);
}

Konkurensi Tanpa Rasa Khawatir dengan Rust

Sistem kepemilikan dan tipe Rust sangat penting untuk mencapai konkurensi tanpa rasa khawatir. Dengan menerapkan aturan saat kompilasi, Rust mencegah bug konkurensi umum seperti perlombaan data.

  • Kepemilikan mencegah beberapa referensi yang dapat diubah ke data yang sama.
  • Kata kunci move memastikan data ditransfer dengan aman ke thread baru.
  • Pengiriman pesan (mpsc) sepenuhnya menghindari memori bersama, sehingga komunikasi aman berdasarkan rancangan.

Mekanisme ini memungkinkan Anda menulis kode konkuren dengan percaya diri, karena mengetahui bahwa kompiler akan menangkap banyak masalah yang mungkin terjadi.

Pemeriksaan Konsep Konkurensi

Pernyataan mana berikut ini tentang primitif konkurensi Rust yang TRUE?

Rangkuman: Thread & Pengiriman Pesan

Bagus sekali! Anda telah mempelajari dasar-dasar konkurensi tanpa rasa khawatir di Rust:

  • Kita membuat thread baru menggunakan std::thread::spawn.
  • Kita menggunakan JoinHandle::join() untuk menunggu thread selesai.
  • Kata kunci move mentransfer kepemilikan data ke dalam thread dengan aman.
  • std::sync::mpsc menyediakan sistem pengiriman pesan yang andal untuk komunikasi antarthread.
  • Aturan kepemilikan Rust mencegah perlombaan data saat kompilasi, sehingga pemrograman konkuren menjadi lebih aman.

Pelajaran ini memberikan dasar yang kuat untuk membangun aplikasi yang responsif dan efisien. Teruslah berlatih!

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Konkurensi Tanpa Rasa Takut dengan Thread” gratis?

Ya — teks lengkap “Konkurensi Tanpa Rasa Takut dengan 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 3 pelajaran total.

Apa yang akan aku pelajari di “Konkurensi Tanpa Rasa Takut dengan Thread”?

Pelajari primitif Rust untuk pemrograman konkuren, termasuk thread dan pengiriman pesan, sambil memastikan bebas dari perlombaan data. 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 3 dari 3.

Berapa lama pelajaran “Konkurensi Tanpa Rasa Takut dengan 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

  1. Penunjuk Cerdas Box, Rc, dan Arc
  2. Mutabilitas Internal: RefCell, Cell
  3. Konkurensi Tanpa Rasa Takut dengan Thread
← Kembali ke Learn Rust Coding