Fungsi Tunggu

Fungsi tunggu memungkinkan utas memblokir eksekusinya sendiri. Fungsi tunggu tidak kembali sampai kriteria yang ditentukan telah terpenuhi. Jenis fungsi tunggu menentukan set kriteria yang digunakan. Ketika fungsi tunggu dipanggil, fungsi tersebut memeriksa apakah kriteria tunggu telah terpenuhi. Jika kriteria belum terpenuhi, utas panggilan memasuki status tunggu hingga kondisi kriteria tunggu telah terpenuhi atau interval waktu habis yang ditentukan berlalu.

Fungsi Tunggu objek tunggal

Fungsi SignalObjectAndWait, WaitForSingleObject, dan WaitForSingleObjectEx memerlukan handel ke satu objek sinkronisasi. Fungsi-fungsi ini kembali ketika salah satu hal berikut terjadi:

  • Objek yang ditentukan dalam status disinyalir.
  • Interval waktu habis berlalu. Interval waktu habis dapat diatur ke INFINITE untuk menentukan bahwa waktu tunggu tidak akan habis.

Fungsi SignalObjectAndWait memungkinkan utas panggilan untuk mengatur status objek secara atomik untuk memberi sinyal dan menunggu status objek lain diatur ke sinyal.

Fungsi Tunggu Multi-objek

Fungsi WaitForMultipleObjects, WaitForMultipleObjectsEx, MsgWaitForMultipleObjects, dan MsgWaitForMultipleObjectsEx memungkinkan alur panggilan untuk menentukan array yang berisi satu atau beberapa handel objek sinkronisasi. Fungsi-fungsi ini kembali ketika salah satu hal berikut terjadi:

  • Status salah satu objek yang ditentukan diatur ke sinyal atau status semua objek telah diatur ke sinyal. Anda mengontrol apakah satu atau semua status akan digunakan dalam panggilan fungsi.
  • Interval waktu habis berlalu. Interval waktu habis dapat diatur ke INFINITE untuk menentukan bahwa waktu tunggu tidak akan habis.

Fungsi MsgWaitForMultipleObjects dan MsgWaitForMultipleObjectsEx memungkinkan Anda menentukan objek peristiwa input dalam array penanganan objek. Ini dilakukan ketika Anda menentukan jenis input untuk menunggu dalam antrean input utas. Misalnya, utas dapat menggunakan MsgWaitForMultipleObjects untuk memblokir eksekusinya hingga status objek tertentu telah diatur ke sinyal dan ada input mouse yang tersedia dalam antrean input utas. Utas dapat menggunakan fungsi GetMessage atau PeekMessageA atau PeekMessageW untuk mengambil input.

Saat menunggu status semua objek diatur ke sinyal, fungsi multi-objek ini tidak memodifikasi status objek yang ditentukan sampai status semua objek telah diatur memberi sinyal. Misalnya, status objek mutex dapat disinyalir, tetapi utas panggilan tidak mendapatkan kepemilikan sampai status objek lain yang ditentukan dalam array juga telah diatur ke sinyal. Sementara itu, beberapa utas lain mungkin mendapatkan kepemilikan objek mutex, sehingga mengatur statusnya ke nonsignaled.

Saat menunggu status objek tunggal diatur ke sinyal, fungsi multi-objek ini memeriksa handel dalam array agar dimulai dengan indeks 0, hingga salah satu objek diberi sinyal. Jika beberapa objek menjadi sinyal, fungsi mengembalikan indeks handel pertama dalam array yang objeknya diberi sinyal.

Fungsi Tunggu yang Dapat Diperingatkan

Fungsi MsgWaitForMultipleObjectsEx, SignalObjectAndWait, WaitForMultipleObjectsEx, dan WaitForSingleObjectEx berbeda dari fungsi tunggu lainnya karena fungsi tunggu dapat secara opsional melakukan operasi tunggu yang dapat diperingatkan. Dalam operasi tunggu yang dapat diperingatkan, fungsi dapat kembali ketika kondisi yang ditentukan terpenuhi, tetapi juga dapat kembali jika sistem mengantrekan rutinitas penyelesaian I/O atau APC untuk dieksekusi oleh utas tunggu. Untuk informasi selengkapnya tentang operasi tunggu yang dapat diperingatkan dan rutinitas penyelesaian I/O, lihat Sinkronisasi dan Input dan Output yang Tumpang Tindih. Untuk informasi selengkapnya tentang APC, lihat Panggilan Prosedur Asinkron.

Fungsi Tunggu Terdaftar

Fungsi RegisterWaitForSingleObject berbeda dari fungsi tunggu lainnya karena operasi tunggu dilakukan oleh utas dari kumpulan utas. Ketika kondisi yang ditentukan terpenuhi, fungsi panggilan balik dijalankan oleh utas pekerja dari kumpulan utas.

Secara default, operasi tunggu terdaftar adalah operasi multi-tunggu. Sistem mengatur ulang timer setiap kali peristiwa diberi sinyal (atau interval waktu habis berlalu) hingga Anda memanggil fungsi UnregisterWaitEx untuk membatalkan operasi. Untuk menentukan bahwa operasi tunggu harus dijalankan hanya sekali, atur parameter dwFlags dari RegisterWaitForSingleObject ke WT_EXECUTEONLYONCE.

Jika utas memanggil fungsi yang menggunakan APC, atur parameter dwFlagsregisterWaitForSingleObject ke WT_EXECUTEINPERSISTENTTHREAD.

Menunggu Alamat

Utas dapat menggunakan fungsi WaitOnAddress untuk menunggu nilai alamat target berubah dari beberapa nilai yang tidak diinginkan ke nilai lainnya. Ini memungkinkan utas menunggu nilai berubah tanpa harus memutar atau menangani masalah sinkronisasi yang dapat muncul ketika utas menangkap nilai yang tidak diinginkan tetapi nilai berubah sebelum utas dapat menunggu.

WaitOnAddress kembali saat kode yang memodifikasi nilai target memberi sinyal perubahan dengan memanggil WakeByAddressSingle untuk membangunkan satu utas tunggu atau WakeByAddressAll untuk membangunkan semua utas tunggu. Jika interval waktu habis ditentukan dengan WaitOnAddress dan tidak ada utas yang memanggil fungsi bangun, fungsi akan kembali saat interval waktu habis berlalu. Jika tidak ada interval waktu habis yang ditentukan, utas akan menunggu tanpa batas waktu.

Fungsi Tunggu dan Interval Waktu Habis

Akurasi interval waktu habis yang ditentukan tergantung pada resolusi jam sistem. Jam sistem "berdetak" pada tingkat konstanta. Jika interval waktu habis kurang dari resolusi jam sistem, waktu tunggu mungkin habis dalam waktu kurang dari durasi waktu yang ditentukan. Jika interval waktu habis lebih besar dari satu tanda centang tetapi kurang dari dua, penantian dapat berada di mana saja antara satu dan dua kutu, dan seterusnya.

Untuk meningkatkan akurasi interval waktu habis untuk fungsi tunggu, panggil fungsi timeGetDevCaps untuk menentukan resolusi timer minimum yang didukung dan fungsi timeBeginPeriod untuk mengatur resolusi timer ke minimumnya. Berhati-hatilah saat memanggil timeBeginPeriod, karena panggilan yang sering dapat secara signifikan memengaruhi jam sistem, penggunaan daya sistem, dan penjadwal. Jika Anda memanggil timeBeginPeriod, panggil satu kali di awal aplikasi dan pastikan untuk memanggil fungsi timeEndPeriod di akhir aplikasi.

Fungsi Tunggu dan Objek Sinkronisasi

Fungsi tunggu dapat memodifikasi status beberapa jenis objek sinkronisasi. Modifikasi hanya terjadi untuk objek atau objek yang status sinyalnya menyebabkan fungsi kembali. Fungsi tunggu dapat mengubah status objek sinkronisasi sebagai berikut:

  • Jumlah objek semaphore berkurang satu, dan status semaphore diatur ke nonsignaled jika jumlahnya nol.
  • Status mutex, peristiwa reset otomatis, dan objek pemberitahuan perubahan diatur ke nonsignaled.
  • Status timer sinkronisasi diatur ke nonsignaled.
  • Status peristiwa reset manual, timer reset manual, proses, utas, dan objek input konsol tidak terpengaruh oleh fungsi tunggu.

Fungsi Tunggu dan Membuat Windows

Anda harus berhati-hati saat menggunakan fungsi tunggu dan kode yang secara langsung atau tidak langsung membuat jendela. Jika utas membuat jendela apa pun, utas harus memproses pesan. Siaran pesan dikirim ke semua jendela dalam sistem. Jika Anda memiliki utas yang menggunakan fungsi tunggu tanpa interval waktu habis, sistem akan mengalami kebuntuan. Dua contoh kode yang secara tidak langsung membuat jendela adalah DDE dan fungsi CoInitialize . Oleh karena itu, jika Anda memiliki utas yang membuat jendela, gunakan MsgWaitForMultipleObjects atau MsgWaitForMultipleObjectsEx, daripada fungsi tunggu lainnya.