Melihat melalui artikel ini tentang keamanan konkurensi Rust:
http://blog.rust-lang.org/2015/04/10/Fearless-Concurrency.html
Saya bertanya-tanya berapa banyak dari ide-ide ini dapat dicapai di C ++ 11 (atau lebih baru). Secara khusus dapatkah saya membuat kelas pemilik yang mentransfer kepemilikan ke metode apa pun yang dapat dilewati? Tampaknya C ++ memiliki begitu banyak cara untuk melewatkan variabel sehingga tidak mungkin, tetapi mungkin saya bisa memberikan beberapa batasan pada kelas atau templat untuk memastikan bahwa beberapa kode templat dijalankan dengan setiap metode yang dilewati?
concurrency
c++11
rust
Brannon
sumber
sumber
&
tidak memerlukan promosi untuk digunakan. Jika Anda mencoba untuk mendapatkan&mut
sementara Anda masih punya referensi lain (bisa berubah atau tidak) untuk item yang sama, Anda tidak akan dapat mengkompilasi.RefCell<T>
memindahkan tanda centang untuk menjalankan waktu, jadi Anda akan panik jika mencoba.borrow_mut()
sesuatu yang sudah aktif.borrow()
atau.borrow_mut()
. Rust juga memilikiRc<T>
(berbagi memiliki penunjuk) dan saudara kandungnyaWeak<T>
, tetapi itu adalah tentang kepemilikan, bukan mutabilitas. TempelkanRefCell<T>
bagian dalamnya untuk berubah-ubah.Jawaban:
C ++ memiliki tiga cara untuk meneruskan parameter ke fungsi: dengan nilai, dengan referensi nilai, dan dengan referensi nilai. Dari jumlah tersebut, melewati nilai menciptakan kepemilikan dalam arti bahwa fungsi yang dipanggil menerima salinannya sendiri, dan memberikan referensi nilai menunjukkan bahwa nilai tersebut dapat dikonsumsi, yaitu tidak akan lagi digunakan oleh pemanggil. Melewati dengan referensi nilai berarti bahwa objek tersebut sementara dipinjam dari pemanggil.
Namun, ini cenderung “berdasarkan kesepakatan” dan tidak selalu dapat diperiksa oleh kompiler. Dan Anda dapat secara tidak sengaja mengubah referensi nilai menjadi referensi nilai menggunakan
std::move()
. Secara konkret, ada tiga masalah:Referensi dapat hidup lebih lama dari objek yang dirujuk. Sistem seumur hidup Rust mencegah hal ini.
Mungkin ada lebih dari satu referensi yang bisa berubah / non-const aktif kapan saja. Pemeriksa pinjaman Rust mencegah hal ini.
Anda tidak dapat menyisih dari referensi. Anda tidak dapat melihat di situs panggilan apakah fungsi itu membuat referensi ke objek Anda, tanpa mengetahui tanda tangan dari fungsi yang dipanggil. Oleh karena itu Anda tidak dapat secara andal mencegah referensi, baik dengan menghapus metode khusus kelas Anda maupun dengan mengaudit situs panggilan untuk kepatuhan dengan beberapa panduan gaya "tanpa referensi".
Masalah seumur hidup adalah tentang keamanan memori dasar. Tentu saja ilegal menggunakan referensi ketika objek yang dirujuk telah kedaluwarsa. Tetapi sangat mudah untuk melupakan masa hidup ketika Anda menyimpan referensi dalam suatu objek, khususnya ketika objek itu hidup lebih lama dari ruang lingkup saat ini. Sistem tipe C ++ tidak dapat menjelaskan hal ini karena sama sekali tidak memodelkan objek seumur hidup.
The
std::weak_ptr
pointer pintar tidak semantik kepemilikan encode mirip dengan referensi polos, tetapi membutuhkan bahwa objek direferensikan dikelola melaluishared_ptr
, yaitu adalah referensi-dihitung. Ini bukan abstraksi tanpa biaya.Sementara C ++ memiliki sistem const, ini tidak melacak apakah suatu objek dapat dimodifikasi, tetapi melacak apakah suatu objek dapat dimodifikasi melalui referensi tertentu . Itu tidak memberikan jaminan yang cukup untuk "konkurensi tanpa rasa takut". Sebaliknya, Rust menjamin bahwa jika ada referensi yang bisa berubah aktif yang merupakan satu-satunya referensi ("Saya adalah satu-satunya yang dapat mengubah objek ini") dan jika ada referensi yang tidak bisa diubah maka semua referensi ke objek tidak dapat diubah ("Selagi aku bisa membaca dari objek, tidak ada yang bisa mengubahnya").
Di C ++ Anda mungkin tergoda untuk menjaga akses ke objek melalui penunjuk pintar dengan mutex. Tetapi seperti yang telah dibahas di atas begitu kita memiliki referensi, ia dapat lolos dari umur yang diharapkan. Oleh karena itu penunjuk pintar semacam itu tidak dapat menjamin bahwa itu adalah satu-satunya titik akses ke objek yang dikelola. Skema seperti itu mungkin benar-benar berhasil dalam praktik karena sebagian besar programmer tidak ingin menyabot diri mereka sendiri, tetapi dari sudut pandang tipe sistem ini masih sepenuhnya tidak sehat.
Masalah umum dengan pointer cerdas adalah bahwa mereka adalah perpustakaan di atas bahasa inti. Seperangkat fitur bahasa inti memungkinkan pointer cerdas ini, mis.
std::unique_ptr
Kebutuhan pemindah-konstruktor. Tetapi mereka tidak dapat memperbaiki kekurangan dalam bahasa inti. Kemampuan untuk secara implisit membuat referensi ketika memanggil suatu fungsi dan untuk menggantung referensi bersama berarti bahwa bahasa inti C ++ tidak sehat. Ketidakmampuan untuk membatasi referensi yang dapat diubah menjadi satu berarti bahwa C ++ tidak dapat menjamin keamanan terhadap kondisi balapan dengan segala jenis konkurensi.Tentu saja dalam banyak hal C ++ dan Rust lebih mirip daripada disalike, khususnya mengenai konsep-konsep mereka tentang kehidupan objek yang ditentukan secara statis. Tetapi sementara dimungkinkan untuk menulis program C ++ yang benar (asalkan tidak ada programmer yang melakukan kesalahan), Rust menjamin kebenaran mengenai properti yang dibahas.
sumber