C ++ - faq umumnya dikelola oleh komunitas C ++, dan Anda dapat datang dan meminta pendapat kami di obrolan kami.
Anak Anjing
@DeadMG: Saya tidak mengetahui C ++ - faq dan etiketnya, itu disarankan dalam komentar.
K-ballo
2
Di mana Anda mendengar bahwa const berarti thread-safe?
Mark B
2
@ Mark B: Herb Sutter dan Bjarne Stroustrup mengatakannya di Standard C ++ Foundation , lihat tautan di bagian bawah jawaban.
K-ballo
CATATAN BAGI MEREKA YANG DATANG KE SINI: pertanyaan sebenarnya BUKANLAH apakah constberarti thread-safe. Itu tidak masuk akal, karena jika tidak, itu berarti Anda harus dapat melanjutkan dan menandai setiap metode aman utas sebagai const. Sebaliknya, pertanyaan yang sebenarnya kami tanyakan adalah constIMPLIES thread-safe, dan itulah inti diskusi ini.
pengguna541686
Jawaban:
132
Saya dengar itu constberarti thread-safe di C ++ 11 . Benarkah itu?
Itu agak benar ...
Inilah yang dikatakan Bahasa Standar tentang keamanan thread:
[1.10 / 4]
Dua evaluasi ekspresi konflik jika salah satunya mengubah lokasi memori (1.7) dan yang lainnya mengakses atau mengubah lokasi memori yang sama.
[1.10 / 21]
Eksekusi program berisi balapan data jika berisi dua tindakan yang saling bertentangan di utas berbeda, setidaknya salah satunya tidak atom, dan tidak ada yang terjadi sebelum yang lain. Setiap data race menghasilkan perilaku yang tidak terdefinisi.
yang tidak lain adalah kondisi yang cukup untuk terjadinya data race :
Ada dua atau lebih tindakan yang dilakukan pada waktu yang sama pada suatu hal; dan
Setidaknya salah satunya adalah menulis.
The Library Standard dibangun di atas itu, akan sedikit lebih jauh:
[17.6.5.9/1]
Bagian ini menetapkan persyaratan yang harus dipenuhi oleh implementasi untuk mencegah balapan data (1.10). Setiap fungsi perpustakaan standar harus memenuhi setiap persyaratan kecuali ditentukan lain. Penerapan dapat mencegah data race dalam kasus selain yang ditentukan di bawah ini.
[17.6.5.9/3]
Fungsi pustaka standar C ++ tidak boleh secara langsung atau tidak langsung mengubah objek (1.10) yang dapat diakses oleh utas selain utas saat ini kecuali objek diakses secara langsung atau tidak langsung melaluiargumennon- konst fungsi, termasukthis.
yang dengan kata sederhana mengatakan bahwa ia mengharapkan operasi pada constobjek menjadi thread-safe . Ini berarti bahwa Standard Library tidak akan memperkenalkan data race selama operasi pada constobjek jenis Anda juga
Sepenuhnya terdiri dari bacaan --yaitu, tidak ada tulisan--; atau
Menyinkronkan penulisan secara internal.
Jika harapan ini tidak berlaku untuk salah satu tipe Anda, maka menggunakannya secara langsung atau tidak langsung bersama dengan komponen Perpustakaan Standar dapat mengakibatkan perlombaan data . Kesimpulannya, constberarti thread-safe dari sudut pandang Standard Library . Penting untuk dicatat bahwa ini hanyalah sebuah kontrak dan tidak akan diberlakukan oleh kompiler, jika Anda melanggarnya, Anda mendapatkan perilaku yang tidak terdefinisi dan Anda sendirian. Apakah consthadir atau tidak tidak akan mempengaruhi generasi kode --at setidaknya tidak dalam hal ras data yang -.
Apakah itu berarti constsekarang setara dengan Java 's synchronized?
Tidak . Tidak semuanya...
Pertimbangkan kelas yang terlalu disederhanakan berikut ini yang merepresentasikan persegi panjang:
The anggota-fungsiarea adalah benang-aman ; bukan karena itu const, tetapi karena seluruhnya terdiri dari operasi baca. Tidak ada penulisan yang terlibat, dan setidaknya satu penulisan yang terlibat diperlukan agar perlombaan data terjadi. Itu berarti Anda dapat memanggil areadari sebanyak mungkin utas yang Anda inginkan dan Anda akan mendapatkan hasil yang benar setiap saat.
Catatan bahwa ini tidak berarti bahwa rectadalah benang-aman . Faktanya, mudah untuk melihat bagaimana jika panggilan ke areaterjadi pada saat yang sama dengan panggilan ke set_sizeyang diberikan rect, kemudian areadapat menghitung hasilnya berdasarkan lebar lama dan tinggi baru (atau bahkan pada nilai yang kacau) .
Tapi tidak apa-apa, rectbukankah constitu bahkan diharapkan tidak aman untuk thread sama sekali. const rectSebaliknya, objek yang dideklarasikan akan aman untuk thread karena tidak ada penulisan yang memungkinkan (dan jika Anda mempertimbangkan const_cast-ing sesuatu yang awalnya dideklarasikan constmaka Anda mendapatkan perilaku yang tidak ditentukan dan hanya itu).
Jadi apa artinya itu?
Mari kita asumsikan - demi argumen - bahwa operasi perkalian sangat mahal dan sebaiknya kita menghindarinya jika memungkinkan. Kami dapat menghitung area hanya jika diminta, lalu menyimpannya dalam cache jika diminta lagi di masa mendatang:
[Jika contoh ini tampak terlalu artifisial, Anda dapat menggantinya secara mental intdengan bilangan bulat yang dialokasikan secara dinamis yang sangat besar yang secara inheren tidak aman untuk utas dan yang perkaliannya sangat mahal.]
Fungsi anggotaarea tidak lagi aman untuk thread , sekarang sedang menulis dan tidak disinkronkan secara internal. Apakah ini masalah? Panggilan ke areadapat terjadi sebagai bagian dari konstruktor salinan objek lain, konstruktor tersebut dapat dipanggil oleh beberapa operasi pada wadah standar , dan pada saat itu pustaka standar mengharapkan operasi ini berperilaku sebagai pembacaan dalam kaitannya dengan balapan data . Tapi kami sedang menulis!
Segera setelah kami menempatkan rectdalam wadah standar --directly atau indirectly-- kita memasuki kontrak dengan Standard Library . Untuk terus melakukan penulisan dalam suatu constfungsi sambil tetap mematuhi kontrak tersebut, kita perlu menyinkronkan penulisan tersebut secara internal:
Perhatikan bahwa kami membuat areafungsi thread-safe , tetapi rectmasih belum aman untuk thread . Panggilan untuk areaterjadi pada saat yang sama dengan panggilan ke set_sizemungkin masih menghitung nilai yang salah, karena penugasan ke widthdan heighttidak dilindungi oleh mutex.
Jika kita benar-benar menginginkan thread-saferect , kita akan menggunakan sinkronisasi primitif untuk melindungi non-thread-saferect .
Apakah mereka kehabisan kata kunci ?
Ya begitulah. Mereka telah kehabisan kata kunci sejak hari pertama.
@ Ben Voigt: Menurut pemahaman saya, spesifikasi C ++ 11 untuk std::stringworded dengan cara yang sudah melarang KK . Saya tidak ingat secara spesifik, meskipun ...
K-ballo
3
@BenVoigt: Tidak. Ini hanya akan mencegah hal-hal seperti itu tidak disinkronkan- yaitu, tidak aman untuk utas. C ++ 11 sudah secara eksplisit melarang KK- bagian khusus ini tidak ada hubungannya dengan itu, dan tidak akan melarang KK.
Anak Anjing
2
Menurut saya, ada celah logis. [17.6.5.9/3] melarang "terlalu banyak" dengan mengatakan "tidak akan secara langsung atau tidak langsung mengubah"; itu harus mengatakan "tidak akan secara langsung atau tidak langsung memperkenalkan perlombaan data", kecuali menulis atom di suatu tempat didefinisikan bukan sebagai "modifikasi". Tetapi saya tidak dapat menemukan ini di mana pun.
Andy Prowl
1
Saya mungkin membuat keseluruhan poin saya sedikit lebih jelas di sini: isocpp.org/blog/2012/12/… Terima kasih telah mencoba membantu.
Andy Prowl
1
Kadang-kadang saya bertanya-tanya siapa yang sebenarnya (atau yang terlibat langsung) yang sebenarnya bertanggung jawab untuk menuliskan beberapa paragraf standar seperti ini.
const
berarti thread-safe. Itu tidak masuk akal, karena jika tidak, itu berarti Anda harus dapat melanjutkan dan menandai setiap metode aman utas sebagaiconst
. Sebaliknya, pertanyaan yang sebenarnya kami tanyakan adalahconst
IMPLIES thread-safe, dan itulah inti diskusi ini.Jawaban:
Itu agak benar ...
Inilah yang dikatakan Bahasa Standar tentang keamanan thread:
yang tidak lain adalah kondisi yang cukup untuk terjadinya data race :
The Library Standard dibangun di atas itu, akan sedikit lebih jauh:
yang dengan kata sederhana mengatakan bahwa ia mengharapkan operasi pada
const
objek menjadi thread-safe . Ini berarti bahwa Standard Library tidak akan memperkenalkan data race selama operasi padaconst
objek jenis Anda jugaJika harapan ini tidak berlaku untuk salah satu tipe Anda, maka menggunakannya secara langsung atau tidak langsung bersama dengan komponen Perpustakaan Standar dapat mengakibatkan perlombaan data . Kesimpulannya,
const
berarti thread-safe dari sudut pandang Standard Library . Penting untuk dicatat bahwa ini hanyalah sebuah kontrak dan tidak akan diberlakukan oleh kompiler, jika Anda melanggarnya, Anda mendapatkan perilaku yang tidak terdefinisi dan Anda sendirian. Apakahconst
hadir atau tidak tidak akan mempengaruhi generasi kode --at setidaknya tidak dalam hal ras data yang -.Tidak . Tidak semuanya...
Pertimbangkan kelas yang terlalu disederhanakan berikut ini yang merepresentasikan persegi panjang:
The anggota-fungsi
area
adalah benang-aman ; bukan karena ituconst
, tetapi karena seluruhnya terdiri dari operasi baca. Tidak ada penulisan yang terlibat, dan setidaknya satu penulisan yang terlibat diperlukan agar perlombaan data terjadi. Itu berarti Anda dapat memanggilarea
dari sebanyak mungkin utas yang Anda inginkan dan Anda akan mendapatkan hasil yang benar setiap saat.Catatan bahwa ini tidak berarti bahwa
rect
adalah benang-aman . Faktanya, mudah untuk melihat bagaimana jika panggilan kearea
terjadi pada saat yang sama dengan panggilan keset_size
yang diberikanrect
, kemudianarea
dapat menghitung hasilnya berdasarkan lebar lama dan tinggi baru (atau bahkan pada nilai yang kacau) .Tapi tidak apa-apa,
rect
bukankahconst
itu bahkan diharapkan tidak aman untuk thread sama sekali.const rect
Sebaliknya, objek yang dideklarasikan akan aman untuk thread karena tidak ada penulisan yang memungkinkan (dan jika Anda mempertimbangkanconst_cast
-ing sesuatu yang awalnya dideklarasikanconst
maka Anda mendapatkan perilaku yang tidak ditentukan dan hanya itu).Mari kita asumsikan - demi argumen - bahwa operasi perkalian sangat mahal dan sebaiknya kita menghindarinya jika memungkinkan. Kami dapat menghitung area hanya jika diminta, lalu menyimpannya dalam cache jika diminta lagi di masa mendatang:
[Jika contoh ini tampak terlalu artifisial, Anda dapat menggantinya secara mental
int
dengan bilangan bulat yang dialokasikan secara dinamis yang sangat besar yang secara inheren tidak aman untuk utas dan yang perkaliannya sangat mahal.]Fungsi anggota
area
tidak lagi aman untuk thread , sekarang sedang menulis dan tidak disinkronkan secara internal. Apakah ini masalah? Panggilan kearea
dapat terjadi sebagai bagian dari konstruktor salinan objek lain, konstruktor tersebut dapat dipanggil oleh beberapa operasi pada wadah standar , dan pada saat itu pustaka standar mengharapkan operasi ini berperilaku sebagai pembacaan dalam kaitannya dengan balapan data . Tapi kami sedang menulis!Segera setelah kami menempatkan
rect
dalam wadah standar --directly atau indirectly-- kita memasuki kontrak dengan Standard Library . Untuk terus melakukan penulisan dalam suatuconst
fungsi sambil tetap mematuhi kontrak tersebut, kita perlu menyinkronkan penulisan tersebut secara internal:Perhatikan bahwa kami membuat
area
fungsi thread-safe , tetapirect
masih belum aman untuk thread . Panggilan untukarea
terjadi pada saat yang sama dengan panggilan keset_size
mungkin masih menghitung nilai yang salah, karena penugasan kewidth
danheight
tidak dilindungi oleh mutex.Jika kita benar-benar menginginkan thread-safe
rect
, kita akan menggunakan sinkronisasi primitif untuk melindungi non-thread-saferect
.Ya begitulah. Mereka telah kehabisan kata kunci sejak hari pertama.
Sumber : Anda tidak tahu
const
danmutable
- Herb Suttersumber
std::string
worded dengan cara yang sudah melarang KK . Saya tidak ingat secara spesifik, meskipun ...