unit HandleForm; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type THandleFrm = class(TForm) CreateBtn: TButton; CloseOwnerBtn: TButton; CloseNonOwnerBtn: TButton; RelBtn: TButton; procedure CreateBtnClick(Sender: TObject); procedure CloseOwnerBtnClick(Sender: TObject); procedure CloseNonOwnerBtnClick(Sender: TObject); procedure RelBtnClick(Sender: TObject); private { Private declarations } public { Public declarations } Semaphore: THandle; end; var HandleFrm: THandleFrm; implementation uses HandleThreads; {$R *.DFM} procedure THandleFrm.CreateBtnClick(Sender: TObject); begin Semaphore := CreateSemaphore(nil, 1, 1, nil); WaitForSingleObject(Semaphore, INFINITE); THandleThread.Create(false); THandleThread.Create(false); ShowMessage('Threads Created.'); end; procedure THandleFrm.CloseOwnerBtnClick(Sender: TObject); begin CloseHandle(Semaphore); end; procedure THandleFrm.CloseNonOwnerBtnClick(Sender: TObject); begin ReleaseSemaphore(Semaphore, 1, nil); CloseHandle(Semaphore); end; procedure THandleFrm.RelBtnClick(Sender: TObject); begin ReleaseSemaphore(Semaphore, 1, nil); end; end. unit HandleThreads; interface uses Classes, Windows, SysUtils, Dialogs; type THandleThread = class(TThread) private { Private declarations } protected procedure Execute; override; end; implementation uses HandleForm; procedure THandleThread.Execute; var RetVal: integer; begin RetVal := WaitForSingleObject(HandleFrm.Semaphore, 10000); case RetVal of WAIT_OBJECT_0: ShowMessage('Unblocked: WAIT_OBJECT_0'); WAIT_ABANDONED: ShowMessage('Unblocked: WAIT_ABANDONED'); WAIT_TIMEOUT: ShowMessage('Unblocked: WAIT_TIMEOUT'); else ShowMessage('Unblocked. Unknown return code.'); end; end; end.