Bagikan melalui


Objek Bagian Kritis

Objek bagian penting menyediakan sinkronisasi yang mirip dengan yang disediakan oleh objek mutex, kecuali bahwa bagian penting hanya dapat digunakan oleh utas dari satu proses. Objek bagian penting tidak dapat dibagikan di seluruh proses.

Objek peristiwa, muteks, dan semaphore juga dapat digunakan dalam aplikasi proses tunggal, tetapi objek bagian penting memberikan mekanisme yang sedikit lebih cepat dan lebih efisien untuk sinkronisasi pengecualian timbal balik (pengujian khusus prosesor dan instruksi yang ditetapkan). Seperti objek mutex, objek bagian penting hanya dapat dimiliki oleh satu utas pada satu waktu, yang membuatnya berguna untuk melindungi sumber daya bersama dari akses bersamaan. Tidak seperti objek mutex, tidak ada cara untuk mengetahui apakah bagian penting telah ditinggalkan.

Dimulai dengan Windows Server 2003 dengan Paket Layanan 1 (SP1), utas yang menunggu pada bagian penting tidak memperoleh bagian penting berdasarkan first-come, first-serve. Perubahan ini meningkatkan performa secara signifikan untuk sebagian besar kode. Namun, beberapa aplikasi bergantung pada urutan first-in, first-out (FIFO) dan dapat berkinerja buruk atau tidak sama sekali pada versi Windows saat ini (misalnya, aplikasi yang telah menggunakan bagian penting sebagai pembatas tarif). Untuk memastikan bahwa kode Anda terus berfungsi dengan benar, Anda mungkin perlu menambahkan tingkat sinkronisasi tambahan. Misalnya, Anda memiliki utas produsen dan utas konsumen yang menggunakan objek bagian penting untuk menyinkronkan pekerjaan mereka. Buat dua objek peristiwa, satu untuk setiap utas yang akan digunakan untuk memberi sinyal bahwa utas lain siap untuk dilanjutkan. Utas konsumen akan menunggu produsen memberi sinyal peristiwanya sebelum memasuki bagian kritis, dan utas produsen akan menunggu utas konsumen memberi sinyal peristiwanya sebelum memasuki bagian kritis. Setelah setiap utas meninggalkan bagian penting, ia memberi sinyal peristiwanya untuk merilis utas lainnya.

Windows Server 2003 dan Windows XP: Utas yang menunggu di bagian kritis ditambahkan ke antrean tunggu; mereka dibangunkan dan umumnya memperoleh bagian kritis dalam urutan ditambahkan ke antrean. Namun, jika utas ditambahkan ke antrean ini pada tingkat yang cukup cepat, performa dapat diturunkan karena waktu yang diperlukan untuk membangunkan setiap utas tunggu.

Proses ini bertanggung jawab untuk mengalokasikan memori yang digunakan oleh bagian penting. Biasanya, ini dilakukan hanya dengan mendeklarasikan variabel jenis CRITICAL_SECTION. Sebelum utas proses dapat menggunakannya, inisialisasi bagian penting dengan menggunakan fungsi InitializeCriticalSection atau InitializeCriticalSectionAndSpinCount .

Utas menggunakan fungsi EnterCriticalSection atau TryEnterCriticalSection untuk meminta kepemilikan bagian penting. Ini menggunakan fungsi LeaveCriticalSection untuk merilis kepemilikan bagian penting. Jika objek bagian penting saat ini dimiliki oleh utas lain, EnterCriticalSection menunggu tanpa batas waktu untuk kepemilikan. Sebaliknya, ketika objek mutex digunakan untuk pengecualian bersama, fungsi tunggu menerima interval waktu habis yang ditentukan. Fungsi TryEnterCriticalSection mencoba memasuki bagian penting tanpa memblokir utas panggilan.

Ketika utas memiliki bagian penting, utas dapat melakukan panggilan tambahan ke EnterCriticalSection atau TryEnterCriticalSection tanpa memblokir eksekusinya. Ini mencegah utas dari kebuntuan itu sendiri sambil menunggu bagian penting yang sudah dimilikinya. Untuk merilis kepemilikannya, utas harus memanggil LeaveCriticalSection satu kali untuk setiap kali memasuki bagian penting. Tidak ada jaminan tentang urutan di mana utas tunggu akan memperoleh kepemilikan bagian penting.

Utas menggunakan fungsi InitializeCriticalSectionAndSpinCount atau SetCriticalSectionSpinCount untuk menentukan jumlah putaran untuk objek bagian penting. Berputar berarti bahwa ketika utas mencoba memperoleh bagian penting yang terkunci, utas memasuki perulangan, memeriksa untuk melihat apakah kunci dilepaskan, dan jika kunci tidak dilepaskan, utas akan tidur. Pada sistem prosesor tunggal, jumlah putaran diabaikan dan jumlah putar bagian kritis diatur ke 0 (nol). Pada sistem multiprosesor, jika bagian penting tidak tersedia, utas panggilan memutar waktu dwSpinCount sebelum melakukan operasi tunggu pada semaphore yang terkait dengan bagian penting. Jika bagian yang penting menjadi gratis selama operasi spin, utas panggilan menghindari operasi tunggu.

Setiap utas proses dapat menggunakan fungsi DeleteCriticalSection untuk merilis sumber daya sistem yang dialokasikan saat objek bagian penting diinisialisasi. Setelah fungsi ini dipanggil, objek bagian penting tidak dapat digunakan untuk sinkronisasi.

Ketika objek bagian penting dimiliki, satu-satunya utas lain yang terpengaruh adalah utas yang menunggu kepemilikan dalam panggilan ke EnterCriticalSection. Utas yang tidak menunggu bebas untuk terus berjalan.

Objek Mutex

Menggunakan Objek Bagian Penting