Semaphore pada Acara C ++

Hari ini saya akan berbicara secara singkat tentang bagaimana saya menerapkan semafor berdasarkan objek sinkronisasi "Acara".

Pertama melalui definisi.

1. Apa itu sinkronisasi dan mengapa diperlukan?


Jelas, kita dapat melakukan serangkaian tindakan dalam beberapa cara. Yang paling sederhana - secara berurutan dan paralel. Implementasi paralel tindakan tertentu dapat dicapai dengan menjalankan berbagai utas. Idenya sederhana: kami menetapkan masing-masing utas beberapa tindakan dasar (atau tidak demikian) dan memulai mereka dalam urutan tertentu. Secara umum, kita dapat meluncurkan semuanya sekaligus - tentu saja, kita akan mendapatkan keuntungan tepat waktu. Ini dapat dimengerti: itu adalah satu hal untuk menghasilkan 10.000 kata satu demi satu, dan hal lain untuk secara bersamaan menghasilkan, misalnya, 100 kata. Penguatan waktu 100 kali lipat (plus atau minus, tidak termasuk penundaan, dll.). Tetapi tugas aslinya mungkin melibatkan urutan tindakan yang ketat.

Sebagai contoh:

  • Buka file
  • Tulis teks ke file
  • Tutup file

Contoh rumah kaca diambil secara khusus (jelas bahwa tidak diperlukan paralelisme di sini, semuanya dapat dilakukan secara berurutan), tetapi sebagai tugas pelatihan, ia akan benar-benar berfungsi, dan yang paling penting, kebutuhan untuk pelaksanaan yang konsisten terlihat jelas pada contohnya. Atau di sini adalah contoh lain, sedikit berbeda:

  • Hasilkan tiga urutan angka acak
  • Tampilkan secara berurutan

Di sini, titik pertama dapat dilakukan secara bersamaan oleh tiga utas yang berbeda, tetapi yang terakhir, kesimpulan, harus dilakukan secara berurutan, dan hanya setelah mengerjakan titik pertama.

Secara umum, tugas paralelisme bisa sangat berbeda dan beberapa alat diperlukan untuk menyinkronkan utas.

2. Alat untuk sinkronisasi utas


Windows.h mengimplementasikan cukup banyak alat sinkronisasi biasa (yang disebut "objek sinkronisasi"). Di antara yang utama adalah: wilayah kritis, peristiwa, mutex, semaphore. Ya, untuk semaphore sudah ada implementasi di windows.h. "Jadi mengapa memprogramnya?" Anda bertanya. Pertama-tama, untuk merasakan bagaimana cara kerjanya. Dan, kedua, latihan ekstra C ++ belum menghentikan siapa pun :)

Karena kami akan menggunakan Acara, kami akan menjelaskan apa itu dan bagaimana menggunakannya.

Acara digunakan untuk memberi tahu utas tertunda. Faktanya, ini adalah sinyal untuk aliran - bisa dipicu atau belum. Dari arti yang sangat dari objek ini, maka ia memiliki beberapa status sinyal dan kemampuan untuk menyesuaikannya (reset / "nyalakan").

Jadi, setelah menghubungkan windows.h kita dapat membuat acara dengan:

HANDLE CreateEvent ( LPSECURITY_ATTRIBUTES lpEventAttributes, //   BOOL bManualReset, //  : TRUE -  BOOL bInitialState, //  : TRUE -  LPCTSTR lpName //   ); 

Jika fungsi berhasil, gagang acara akan dikembalikan. Jika objek tidak dapat dibuat, NULL akan dikembalikan.

Untuk mengubah status acara menjadi sinyal, kami menggunakan fungsi:

 BOOL SetEvent ( HANDLE hEvent //   ); 

Jika berhasil, akan mengembalikan nilai bukan nol.

Sekarang tentang semafor. Semaphore dirancang untuk mengontrol jumlah utas yang berjalan secara bersamaan. Misalkan kita memiliki 1000 utas, tetapi hanya 2 yang dapat bekerja pada satu waktu. Ini adalah jenis penyesuaian yang terjadi dengan bantuan semaphore. Dan fungsi apa yang diterapkan untuk bekerja dengan objek sinkronisasi ini?

Untuk membuat semaphore, mirip dengan acara:

 HANDLE CreateSemaphore ( LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, //   LONG lInitialCount, //     LONG lMaximumCount, //    LPCTSTR lpName //   ); 

Jika berhasil, kami mendapatkan pointer ke semaphore, jika gagal, kami mendapatkan NULL.

Penghitung semaphore terus berubah (utas berjalan dan tempat kosong muncul), sehingga keadaan semaphore harus diubah secara berkala. Ini dilakukan dengan menggunakan fungsi ini:

 BOOL ReleaseSemaphore ( HANDLE hSemaphore, //    LONG lReleaseCount, //     LPLONG lpPreviousCount //   ); 

Jika berhasil, nilai kembali tidak nol.

Juga patut diperhatikan fungsinya:

 DWORD WaitForSingleObject( HANDLE hHandle, //   ,     DWORD dwMilliseconds //     ); 

Dari nilai yang dikembalikan, kami terutama tertarik pada 2: WAIT_OBJECT_0 - berarti bahwa keadaan objek kami adalah sinyal; WAIT_TIMEOUT - kami tidak menunggu status sinyal dari objek dalam waktu yang ditentukan.

3. Tugas itu sendiri


Secara total, tugas kita adalah menulis analog kita pada fungsi reguler. Kami tidak akan terlalu menyulitkan tugas, kami akan membuat "implementasi dalam pendekatan pertama". Hal utama adalah untuk melestarikan karakteristik kuantitatif dari semaphore standar. Kode dengan komentar dapat ditemukan di GitHub .

Karena kesederhanaan tugas itu sendiri, kami tidak akan secara khusus menyulitkan artikel, tetapi mungkin berguna bagi seseorang :)

Source: https://habr.com/ru/post/id476940/


All Articles