7. セマフォ (同期オブジェクト)
セマフォ (Semaphore) は同期オブジェクトの一つです 1。所定の数のスレッドのアクセスを許可します。
スレッドカウンタの最大数が 1 のセマフォをバイナリセマフォと呼び、ミューテックスと同等となります。
7.1. TSemaphore
TSemaphore
クラス 2 を使うと、指定された数のスレッドからしかアクセスできない機構を作る事ができます。TSemaphore
は System.SyncObjs
で定義されています。
最初の書式のコンストラクタではカウンタの初期値が 1 の無名セマフォを作成します。無名セマフォはローカルセマフォで、Critical Section と同等の動作になります。よって、このコンストラクタを使うとミューテックスと同等の動作になります。セマフォの作成に失敗すると EOSError
が発生します。
二番目の書式のコンストラクタでは、名前付きのセマフォを作成します (名前が空でない場合はシステムセマフォ)。セマフォの作成に失敗すると EOSError
が発生します。
三番目の書式のコンストラクタでは名前付きのセマフォを開きます。セマフォが開けなかった場合には EOSError
が発生します。Windows 環境でない場合には名前付きのセマフォを作成します。
constructor Create(UseCOMWait: Boolean = False);
constructor Create(SemaphoreAttributes: PSecurityAttributes; AInitialCount, AMaximumCount: Integer; const Name: string; UseCOMWait: Boolean = False);
constructor Create(DesiredAccess: Cardinal; InheritHandle: Boolean; const Name: string; UseCOMWait: Boolean = False);
最初期のこのクラスは Windows API をラップしたものでした。
Delphi | Windows API |
---|---|
TSemaphore.Create() コンストラクタ | CreateSemaphoreW() |
TSemaphore.Create() コンストラクタ | OpenSemaphoreW() |
TSemaphore.Release() メソッド | ReleaseSemaphore() |
使い方は TMutex
とほぼ同じです。
See also:
- TSemaphore (DocWiki)
- System.SyncObjs.TSemaphore.Create (DocWiki)
- System.SyncObjs.TSemaphore.Acquire (DocWiki)
- System.SyncObjs.TSemaphore.Release (DocWiki)
- System.SyncObjs.THandleObject.WaitFor (DocWiki)
7.1.1. TSemaphore を使った起動数の制御
ちょっとマルチスレッドからは離れますが、プロセス間同期オブジェクト (システムセマフォ) としての使い方です。
TMutex
のような要領で、指定された数しか開けないアプリケーションを作る方法です。
program Project1;
uses
Vcl.Forms,
System.SysUtils,
System.SyncObjs,
WinAPI.Windows,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
const
SEMAPHORE_NAME = 'Global\MyApp';
begin
ReportMemoryLeaksOnShutdown := True;
Application.Initialize;
var oSemaphore, cSemaphore: TSemaphore;
try
oSemaphore := TSemaphore.Create(SEMAPHORE_ALL_ACCESS, False, SEMAPHORE_NAME);
except
on E: EOSError do
cSemaphore := TSemaphore.Create(nil, 2, 3, SEMAPHORE_NAME);
end;
if Assigned(oSemaphore) and (oSemaphore.WaitFor(0) <> wrSignaled) then
begin
Application.MessageBox('3つまでしか開けないよ!', 'エラー', MB_ICONERROR or MB_OK);
end
else
begin
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
if Assigned(oSemaphore) then
oSemaphore.Release;
end;
FreeAndNil(cSemaphore);
FreeAndNil(oSemaphore);
end.
素の Windows API を使った方が簡単な気もします。
7.2. TLightweightSemaphore
TLightweightSemaphore
クラス 3 は軽量なセマフォです。System.SyncObjs
で定義されています。但し、ローカルセマフォとしてしか使えません。
.NET の SemaphoreSlim
クラスに相当します。
See also:
#参考
索引
[ ← 6. ミューテックス (同期オブジェクト) ] [ ↑ 目次へ ] [ → <8> イベント (同期オブジェクト) ]