Saya mengerti dasar-dasar apa ras data itu, dan bagaimana kunci / mutex / semaphore membantu mencegahnya. Tetapi apa yang terjadi jika Anda memiliki "kondisi lomba" pada kunci itu sendiri? Sebagai contoh, dua utas yang berbeda, mungkin dalam aplikasi yang sama, tetapi berjalan pada prosesor yang berbeda, cobalah untuk mendapatkan kunci pada saat yang bersamaan .
Lalu apa yang terjadi? Apa yang dilakukan untuk mencegah hal itu? Apakah itu mustahil, atau sekadar tidak mungkin? Atau apakah ini kondisi balapan yang nyata yang menunggu untuk terjadi?
multithreading
concurrency
locks
Gavin Howard
sumber
sumber
Jawaban:
Mustahil. Ini dapat diimplementasikan dengan cara yang berbeda, misalnya, melalui Compare-and-swap di mana perangkat keras menjamin eksekusi berurutan. Ini bisa menjadi sedikit rumit di hadapan beberapa inti atau bahkan beberapa soket dan memerlukan protokol yang rumit antara inti, tetapi ini semua diurus.
sumber
Pelajari konsep operasi "Uji dan Set" atom.
Pada dasarnya operasi tidak dapat dibagi - dua hal tidak mungkin dilakukan pada waktu yang bersamaan. Ini akan memeriksa nilai, menetapkannya jika jelas, dan mengembalikan nilai seperti saat pengujian. Dalam operasi kunci, hasilnya akan selalu "mengunci == BENAR" setelah tes dan set, satu-satunya perbedaan adalah apakah disetel atau tidak di awal.
Pada tingkat kode mikro dalam prosesor inti tunggal, ini adalah salah satu instruksi yang tidak dapat dibagi, dan mudah diterapkan. Dengan beberapa prosesor dan banyak inti, ini menjadi lebih sulit, tetapi sebagai programmer kita tidak perlu khawatir tentang hal itu, karena dirancang untuk bekerja oleh orang-orang yang benar-benar pintar yang melakukan silikon. Pada dasarnya mereka melakukan hal yang sama - membuat instruksi atom yang merupakan versi percobaan dan set yang mewah
sumber
Sederhananya kode untuk masuk ke bagian kritis dirancang khusus sehingga kondisi balapan tidak akan melanggar pengecualian bersama.
Sebagian besar atom waktu membandingkan dan mengatur loop digunakan yang dijalankan pada tingkat perangkat keras
Karena tidak ada solusi perangkat lunak yang dipelajari dengan baik untuk memungkinkan saling pengecualian.
sumber
Tidak mungkin dua (atau lebih) utas mendapatkan kunci pada saat yang sama. Ada beberapa jenis metode sinkronisasi misalnya:
Tunggu aktif - kunci putar
Kodesemu:
XCHG adalah contoh operasi atom (ada pada arsitektur x86) yang pertama-tama menetapkan nilai baru untuk variabel "kunci" dan kemudian mengembalikan nilai lama. Atomic berarti tidak dapat diinterupsi - dalam contoh di atas antara menetapkan nilai baru dan mengembalikan nilai lama. Atomic - hasil deterministik tidak peduli apa.
Ketika kunci sama dengan 0 utas lainnya dapat masuk ke bagian kritis - sementara loop berakhir.
Penangguhan utas - misalnya menghitung semafor
Ada dua operasi atom
.Wait()
dan.Signal()
dan kami memiliki variabel integer, sebut sajaint currentValue
.Sekarang memecahkan masalah bagian kritis sangat mudah:
Kodesemu:
Biasanya API utas pemrograman Anda harus memberi Anda kemampuan untuk menentukan utas bersamaan maksimum di bagian kritis semaphore. Jelas ada lebih banyak jenis sinkronisasi dalam sistem multithreaded (mutex, monitor, binary semaphore, dll) tetapi mereka didasarkan pada ide-ide di atas. Orang bisa berargumen bahwa metode yang menggunakan penangguhan thread harus lebih disukai daripada menunggu aktif (jadi cpu tidak sia-sia) - itu tidak selalu benar. Ketika utas sedang ditangguhkan - operasi mahal yang disebut sakelar konteks terjadi. Namun masuk akal ketika waktu tunggu pendek (jumlah utas ~ jumlah inti).
sumber