Saat menulis aplikasi multi-thread, hal terpenting adalah mengontrol akses sumber daya yang disinkronkan antar thread untuk memastikan pengoperasian thread yang aman. Win 32 API menyediakan sekumpulan objek sinkronisasi, seperti Semaphore, Mutex, Critical Section, Event, dll., untuk mengatasi masalah ini.
Delphi merangkum objek kejadian dan objek bagian kritis ke dalam objek Tevent dan objek TcriticalSection, membuat penggunaan kedua objek ini menjadi sederhana dan nyaman. Namun, jika Anda ingin menggunakan objek seperti semaphore atau mutex dalam program Delphi, Anda harus menggunakan fungsi API Win32 yang kompleks, yang sangat merepotkan bagi pemrogram yang tidak terbiasa dengan fungsi API Win32. Oleh karena itu, penulis menggunakan Delphi untuk membangun dua kelas untuk merangkum objek semaphore dan mutex (masing-masing TSemaphore dan TMutex), dengan harapan dapat membantu sebagian besar programmer Delphi.
1. Struktur kelas
Pertama-tama kita mengabstraksi objek semaphore dan objek mutex dari API Win32, membuat kelas induk THandleObjectEx, dan kemudian memperoleh dua subkelas Tsemphore dan Tmutex dari kelas induk ini.
Kode sumber kelasnya adalah sebagai berikut:
unit SyncobjsEx;
antarmuka
menggunakan Windows, Pesan, SysUtils, Kelas, Syncobjs;
jenis
THandleObjectEx = kelas(THandleObject)
// THandleObjectEx adalah kelas induk dari kelas pengecualian bersama dan kelas semaphore
Terlindung
Pegangan F: Pegangan;
FLastError: Bilangan Bulat;
publik
destruktor Hancurkan;
prosedur Rilis; timpa;
fungsi WaitFor(Batas Waktu: DWord): TWaitResult;
properti LastError:Integer dibaca FLastError;
properti Menangani: THandle membaca FHandle;
akhir;
TMutex = class(THandleObjectEx)//Kelas yang saling eksklusif
publik
konstruktor Buat(MutexAttributes: PSecurityAttributes; Pemilik Awal: Boolean; Nama const:string);
pelepasan prosedur;
akhir;
TSemaphore = kelas(THandleObjectEx)
//Kelas lampu sinyal
publik
konstruktor Buat(SemaphoreAttributes: PSecurityAttributes;InitialCount:Integer;MaximumCount: integer; const Nama: string);
procedure Release(ReleaseCount: Integer=1;PreviousCount:Pointer=nil kelebihan beban;