Bagikan melalui


Variabel Kondisi

Variabel kondisi adalah primitif sinkronisasi yang memungkinkan utas menunggu hingga kondisi tertentu terjadi. Variabel kondisi adalah objek mode pengguna yang tidak dapat dibagikan di seluruh proses.

Variabel kondisi memungkinkan utas untuk melepaskan kunci secara atomik dan memasuki status tidur. Mereka dapat digunakan dengan bagian penting atau kunci pembaca/penulis ramping (SRW). Variabel kondisi mendukung operasi yang "membangunkan satu" atau "bangun semua" utas tunggu. Setelah utas terbangun, ia memperoleh kembali kunci yang dilepaskannya ketika utas memasuki status tidur.

Perhatikan bahwa pemanggil harus mengalokasikan struktur CONDITION_VARIABLE dan menginisialisasinya dengan memanggil InitializeConditionVariable (untuk menginisialisasi struktur secara dinamis) atau menetapkan CONDITION_VARIABLE_INIT konstanta ke variabel struktur (untuk menginisialisasi struktur secara statis).

Windows Server 2003 dan Windows XP: Variabel kondisi tidak didukung.

Berikut ini adalah fungsi variabel kondisi.

Fungsi variabel kondisi Deskripsi
InitializeConditionVariable Menginisialisasi variabel kondisi.
SleepConditionVariableCS Tidur pada variabel kondisi yang ditentukan dan merilis bagian penting yang ditentukan sebagai operasi atomik.
SleepConditionVariableSRW Tidur pada variabel kondisi yang ditentukan dan melepaskan kunci SRW yang ditentukan sebagai operasi atomik.
WakeAllConditionVariable Membangunkan semua utas yang menunggu variabel kondisi yang ditentukan.
WakeConditionVariable Membangunkan satu utas yang menunggu variabel kondisi yang ditentukan.

 

Pseudocode berikut menunjukkan pola penggunaan umum variabel kondisi.

CRITICAL_SECTION CritSection;
CONDITION_VARIABLE ConditionVar;

void PerformOperationOnSharedData()
{ 
   EnterCriticalSection(&CritSection);

   // Wait until the predicate is TRUE

   while( TestPredicate() == FALSE )
   {
      SleepConditionVariableCS(&ConditionVar, &CritSection, INFINITE);
   }

   // The data can be changed safely because we own the critical 
   // section and the predicate is TRUE

   ChangeSharedData();

   LeaveCriticalSection(&CritSection);

   // If necessary, signal the condition variable by calling
   // WakeConditionVariable or WakeAllConditionVariable so other
   // threads can wake
}

Misalnya, dalam implementasi kunci pembaca/penulis, TestPredicate fungsi akan memverifikasi bahwa permintaan kunci saat ini kompatibel dengan pemilik yang ada. Jika ya, dapatkan kunci; jika tidak, tidur. Untuk contoh yang lebih rinci, lihat Menggunakan Variabel Kondisi.

Variabel kondisi tunduk pada bangun yang melelahkan (yang tidak terkait dengan bangun eksplisit) dan wakeup yang dicuri (utas lain berhasil berjalan sebelum utas woken). Oleh karena itu, Anda harus mencentang ulang predikat (biasanya dalam perulangan sementara ) setelah operasi tidur kembali.

Anda dapat membangunkan utas lain menggunakan WakeConditionVariable atau WakeAllConditionVariable baik di dalam atau di luar kunci yang terkait dengan variabel kondisi. Biasanya lebih baik melepaskan kunci sebelum membangunkan utas lain untuk mengurangi jumlah sakelar konteks.

Seringkali lebih mudah untuk menggunakan lebih dari satu variabel kondisi dengan kunci yang sama. Misalnya, implementasi kunci pembaca/penulis mungkin menggunakan satu bagian penting tetapi variabel kondisi terpisah untuk pembaca dan penulis.

Menggunakan Variabel Kondisi