Saya membaca http://gcc.gnu.org/onlinedocs/libstdc++/manual/shared_ptr.html dan beberapa masalah keamanan untaian masih belum jelas bagi saya:
- Standar menjamin bahwa penghitungan referensi ditangani dengan thread safe dan platform independen, bukan?
- Masalah serupa - jaminan standar bahwa hanya satu utas (memegang referensi terakhir) yang akan memanggil hapus pada objek bersama, bukan?
- shared_ptr tidak menjamin keamanan utas untuk objek yang disimpan di dalamnya?
EDIT:
Kode semu:
// Thread I
shared_ptr<A> a (new A (1));
// Thread II
shared_ptr<A> b (a);
// Thread III
shared_ptr<A> c (a);
// Thread IV
shared_ptr<A> d (a);
d.reset (new A (10));
Memanggil reset () di thread IV akan menghapus instance sebelumnya dari kelas A yang dibuat di thread pertama dan menggantinya dengan instance baru? Selain itu setelah memanggil reset () di thread IV, thread lain hanya akan melihat objek yang baru dibuat?
c++
c++11
shared-ptr
Bodoh
sumber
sumber
make_shared
bukannyanew
Jawaban:
Seperti yang ditunjukkan orang lain, Anda telah menemukannya dengan benar terkait 3 pertanyaan asli Anda.
Tapi bagian akhir dari suntingan Anda
salah. Hanya
d
akan mengarah ke baruA(10)
, dana
,b
danc
akan terus ke titik dengan aslinyaA(1)
. Hal ini terlihat jelas pada contoh singkat berikut ini.(Jelas, saya tidak peduli dengan threading apa pun: itu tidak menjadi faktor dalam
shared_ptr::reset()
perilaku.)Output dari kode ini adalah
sumber
Benar,
shared_ptr
gunakan kenaikan / penurunan atom dari nilai hitungan referensi.Standar menjamin hanya satu utas yang akan memanggil operator hapus pada objek bersama. Saya tidak yakin apakah itu secara khusus menentukan utas terakhir yang menghapus salinan penunjuk bersama akan menjadi yang memanggil hapus (kemungkinan dalam praktiknya ini akan terjadi).
Tidak, objek yang disimpan di dalamnya dapat diedit secara bersamaan oleh beberapa utas.
EDIT: Sedikit tindak lanjut, jika Anda ingin mendapatkan gambaran tentang bagaimana petunjuk bersama bekerja secara umum, Anda mungkin ingin melihat
boost::shared_ptr
sumbernya: http://www.boost.org/doc/libs/1_37_0/boost/shared_ptr.hpp .sumber
std::shared_ptr
tidak aman untuk benang.Penunjuk bersama adalah sepasang dua penunjuk, satu ke objek dan satu ke blok kontrol (menahan penghitung referensi, tautan ke penunjuk lemah ...).
Ada beberapa std :: shared_ptr dan kapan pun mereka mengakses blok kontrol untuk mengubah penghitung referensi, ini aman untuk thread tetapi
std::shared_ptr
itu sendiri TIDAK aman untuk thread atau atomic.Jika Anda menetapkan objek baru untuk
std::shared_ptr
sementara utas lain menggunakannya, itu mungkin berakhir dengan penunjuk objek baru tetapi masih menggunakan penunjuk ke blok kontrol dari objek lama => CRASH.sumber
std::shared_ptr
contoh tidak aman untuk benang. Dari referensi std :: shared_ptr:If multiple threads of execution access the same shared_ptr without synchronization and any of those accesses uses a non-const member function of shared_ptr then a data race will occur;
std::shared_ptr<T>
instance dijamin aman untuk thread ketika selalu digunakan oleh nilai (disalin / dipindahkan) melintasi batas thread. Semua penggunaan lain,std::shared_ptr<T>&
tidak aman melintasi batas utas