Pahami pendekatan konkurensi Rust yang didasarkan pada konsep "konkurensi tanpa rasa takut".

Concurrency adalah kemampuan suatu program untuk menjalankan banyak tugas secara bersamaan pada inti CPU yang sama. Tugas bersamaan berjalan dan selesai dalam waktu yang tumpang tindih tanpa urutan yang ditentukan, tidak seperti paralelisme, di mana berbagai tugas atau subtugas dari tugas yang sama berjalan pada waktu yang sama pada perangkat keras dengan banyak prosesor.

Rust menonjol karena fitur kinerjanya dan dukungan untuk konkurensi dengan cara yang aman dan efisien. Pendekatan Rust terhadap konkurensi didasarkan pada konsep "konkurensi tanpa rasa takut" di mana bahasanya bertujuan untuk memudahkan penulisan yang aman kode bersamaan melalui sistem kepemilikan dan peminjamannya yang menerapkan aturan ketat pada waktu kompilasi untuk mencegah pelacakan data dan memastikan memori keamanan.

Memahami Konkurensi dalam Rust

Rust menyediakan beberapa primitif konkurensi untuk menulis program bersamaan, termasuk utas, pengiriman pesan, mutex, tipe atom, dan async/menunggu untuk pemrograman asinkron.

instagram viewer

Berikut ini ikhtisar konkurensi primitif Rust:

  1. Utas: Karat menyediakan a std:: utas modul di pustaka standarnya untuk membuat dan mengelola utas. Anda dapat menelurkan utas baru dengan benang:: bertelur fungsi. Itu benang:: bertelur mengambil penutupan yang berisi kode untuk dieksekusi. Anda juga dapat menjalankan utas yang dapat berjalan secara paralel, dan Rust menyediakan primitif sinkronisasi untuk mengoordinasikan eksekusinya. Pemeriksa pinjaman memastikan bahwa referensi tidak mengarah pada perilaku yang tidak terduga.
  2. Pesan Lewat: Model konkurensi Rust mendukung pengiriman pesan antar utas. Anda akan menggunakan saluran yang diterapkan melalui std:: sinkronisasi:: mpsc modul untuk menyampaikan pesan. Saluran terdiri dari pemancar (Pengirim) dan penerima (Penerima). Utas dapat mengirim pesan melalui pemancar dan menerimanya melalui penerima. Ini memberikan cara komunikasi yang aman dan tersinkronisasi antar utas.
  3. Mutex dan Jenis Atom: Rust menyediakan primitif sinkronisasi, termasuk mutex (std:: sinkronisasi:: Mutex) dan jenis atom (std:: sinkronisasi:: atom), untuk memastikan akses berbagi data eksklusif. Mutex memungkinkan banyak utas untuk mengakses data secara bersamaan sambil mencegah balapan data. Tipe atom memberikan operasi atom pada data bersama, seperti penambahan penghitung, tanpa memerlukan penguncian eksplisit.
  4. Async/Menunggu dan Berjangka: karat asinkron/menunggu sintaks menyediakan fungsionalitas untuk menulis kode asinkron yang dapat Anda jalankan secara bersamaan. Program asinkron secara efisien menangani tugas yang terikat I/O yang memungkinkan program melakukan tugas lain sambil menunggu operasi I/O lainnya. Karat asinkron/menunggu sintaks didasarkan pada masa depan, dan Anda dapat memberdayakannya dengan async-std atau tokio perpustakaan runtime.

Ulir karat ringan, dan tidak adanya overhead runtime membuatnya sangat cocok untuk aplikasi berperforma tinggi. Primitif konkurensi Rust berintegrasi mulus dengan banyak pustaka dan kerangka kerja untuk kebutuhan konkurensi yang berbeda.

Cara Menggunakan Spawn Threads di Rust

Anda akan menggunakan std:: utas modul untuk menelurkan utas. Itu std:: utas:: bertelur fungsi memungkinkan Anda membuat utas baru yang akan berjalan bersamaan dengan utas utama atau utas lain yang ada di program Anda.

Inilah cara Anda dapat menelurkan utas dengan std:: utas:: bertelur fungsi:

menggunakan std:: utas;

fnutama() {
// Buat utas baru
membiarkan thread_handle = utas:: menelurkan(|| {
// Kode yang dieksekusi di utas baru ada di sini
cetak!("Halo dari utas baru!");
});

// Tunggu hingga utas yang dihasilkan selesai
thread_handle.join().unwrap();

// Kode yang dieksekusi di utas utama berlanjut di sini
cetak!("Halo dari utas utama!");
}

Itu utama fungsi membuat utas baru dengan benang:: bertelur fungsi dengan meneruskan penutupan yang berisi kode untuk eksekusi di utas (dalam hal ini, penutupan adalah fungsi anonim). Penutupan mencetak pesan yang menunjukkan bahwa utas baru sedang berjalan.

Itu bergabung metode pada thread_handle memungkinkan utas utama menunggu utas yang dihasilkan menyelesaikan eksekusi. Dengan menyebut bergabung, fungsi memastikan bahwa utas utama menunggu utas yang dihasilkan selesai sebelum melanjutkan.

Anda dapat menelurkan banyak utas dan menggunakan satu lingkaran atau lainnya Struktur kontrol karat untuk membuat banyak penutupan dan menelurkan utas untuk masing-masing.

menggunakan std:: utas;

fnutama() {
membiarkan num_threads = 5;

membiarkanmut thread_handles = vec![];

untuk Saya di dalam0..num_threads {
membiarkan thread_handle = utas:: menelurkan(bergerak || {
cetak!("Halo dari utas {}", Saya);
});
thread_handles.push (thread_handle);
}

untuk menangani di dalam utas_pegangan {
handle.join().unwrap();
}

cetak!("Semua utas selesai!");
}

Perulangan for memunculkan lima utas, masing-masing ditetapkan ke pengidentifikasi unik Saya dengan variabel loop. Penutupan menangkap nilai Saya dengan bergerak kata kunci yang harus dihindari masalah kepemilikan, dan thread_handles vektor menyimpan utas untuk nanti di bergabung lingkaran.

Setelah menelurkan semua utas, file utama fungsi berulang selama thread_handles vektor, panggilan bergabung pada setiap pegangan, dan menunggu semua utas dieksekusi.

Melewati Pesan Melalui Saluran

Anda dapat menyampaikan pesan melalui utas dengan saluran. Rust menyediakan fungsionalitas untuk pengiriman pesan di std:: sinkronisasi:: mpsc modul. Di Sini, mpsc singkatan dari "multiple producer, single consumer" dan memungkinkan komunikasi antara beberapa thread dengan mengirim dan menerima pesan melalui saluran.

Inilah cara Anda menerapkan pesan yang melewati saluran komunikasi antar-utas dalam program Anda:

menggunakan std:: sinkronisasi:: mpsc;
menggunakan std:: utas;

fnutama() {
// Buat saluran
membiarkan (pengirim, penerima) = mpsc:: channel();

// Menelurkan utas
benang:: muncul(bergerak || {
// Kirim pesan melalui saluran
pengirim.kirim("Halo dari utas!").membuka();
});

// Terima pesan di utas utama
membiarkan pesan_terima = penerima.recv().unwrap();
cetak!("Pesan yang diterima: {}", pesan_terima);
}

Itu utama fungsi membuat saluran dengan mpsc:: saluran() yang mengembalikan a pengirim dan a penerima. Itu pengirim mengirim pesan ke penerima yang menerima pesan. Itu utama fungsi hasil untuk menelurkan utas dan memindahkan kepemilikan Pengirim ke penutupan benang. Di dalam penutupan utas, itu pengirim.kirim() fungsi mengirim pesan melalui saluran.

Itu penerima.recv() fungsi menerima pesan dengan menghentikan eksekusi sampai utas menerima pesan. Itu utama fungsi mencetak pesan ke konsol setelah penerimaan pesan berhasil.

Perhatikan bahwa mengirim pesan melalui saluran menghabiskan pengirim. Jika Anda perlu mengirim pesan dari beberapa utas, Anda dapat mengkloning pengirim dengan pengirim.clone() fungsi.

Selain itu, mpsc modul menyediakan metode lain seperti try_recv(), yang non-pemblokiran mencoba menerima pesan, dan iter(), yang membuat iterator di atas pesan yang diterima.

Pengiriman pesan melalui saluran menyediakan cara yang aman dan nyaman untuk berkomunikasi antar utas sambil menghindari perlombaan data dan memastikan sinkronisasi yang tepat.

Model Kepemilikan dan Peminjaman Rust Menjamin Keamanan Memori

Rust menggabungkan kepemilikan, peminjaman, dan pemeriksa pinjaman untuk menyediakan kerangka kerja pemrograman yang kuat, aman, dan bersamaan.

Pemeriksa pinjaman bertindak sebagai jaring pengaman, mendeteksi potensi masalah pada waktu kompilasi daripada mengandalkan pemeriksaan waktu proses atau pengumpulan sampah.