"Hello, Amigo! Anda ingat bahawa Ellie memberitahu anda tentang masalah yang timbul apabila beberapa utas cuba mengakses sumber yang dikongsi secara serentak, ya?"
"Ya."
"Perkaranya, bukan itu sahaja. Ada masalah kecil lagi."
Seperti yang anda ketahui, komputer mempunyai memori di mana data dan arahan (kod) disimpan, serta pemproses yang melaksanakan arahan ini dan berfungsi dengan data. Pemproses membaca data daripada ingatan, menukarnya dan menulisnya kembali ke ingatan. Untuk mempercepatkan pengiraan, pemproses mempunyai memori "pantas" terbina dalam sendiri: cache.
Pemproses berjalan lebih pantas dengan menyalin pembolehubah dan kawasan memori yang paling kerap digunakan ke cachenya. Kemudian ia membuat semua perubahan dalam ingatan pantas ini. Dan kemudian ia menyalin data kembali ke memori «perlahan». Selama ini, memori perlahan mengandungi pembolehubah lama (tidak berubah!).
Di sinilah masalah timbul. Satu utas menukar pembolehubah , seperti isCancel atau isInterrupted dalam contoh di atas, tetapi utas kedua «tidak melihat perubahan ini , kerana ia berlaku dalam memori pantas. Ini adalah akibat daripada fakta bahawa benang tidak mempunyai akses kepada cache satu sama lain. (Pemproses selalunya mengandungi beberapa teras bebas dan benang boleh berjalan pada teras yang berbeza secara fizikal.)
Mari kita ingat contoh semalam:
Kod | Penerangan |
---|---|
|
Benang «tidak tahu» bahawa benang lain wujud.
Dalam kaedah larian, pembolehubah isCancel dimasukkan ke dalam cache benang kanak-kanak apabila ia digunakan buat kali pertama. Operasi ini bersamaan dengan kod berikut:
Memanggil kaedah batal daripada utas lain akan menukar nilai isCancel dalam memori biasa (perlahan), tetapi tidak dalam cache utas lain. |
|
"Wah! Dan adakah mereka juga menghasilkan penyelesaian yang cantik untuk ini, seperti dengan segerak ?"
"Anda tidak akan percaya!"
Pemikiran pertama adalah untuk melumpuhkan cache, tetapi ini menjadikan program berjalan beberapa kali lebih perlahan. Kemudian penyelesaian yang berbeza muncul.
Kata kunci yang tidak menentu telah dilahirkan. Kami meletakkan kata kunci ini sebelum pengisytiharan berubah untuk menunjukkan bahawa nilainya tidak boleh dimasukkan ke dalam cache. Lebih tepat lagi, ia bukan kerana ia tidak boleh dimasukkan ke dalam cache, tetapi ia sentiasa perlu dibaca dan ditulis ke memori biasa (perlahan).
Berikut ialah cara untuk membetulkan penyelesaian kami supaya semuanya berfungsi dengan baik:
Kod | Penerangan |
---|---|
|
Pengubah suai yang tidak menentu menyebabkan pembolehubah sentiasa dibaca dan ditulis ke memori biasa yang dikongsi oleh semua rangkaian. |
|
"Itu sahaja?"
"Itu sahaja. Simple dan cantik."
GO TO FULL VERSION