「CriticalSectionクラス」の版間の差分
提供:AB開発Wiki
ナビゲーションに移動検索に移動
(Win32クリティカルセクションのラッパクラス) |
細 (ページ CriticalSection クラス を CriticalSectionクラス へ移動: #127) |
||
(同じ利用者による、間の1版が非表示) | |||
1行目: | 1行目: | ||
'''CriticalSection''' クラスは、Windowsのクリティカルセクションをラップするクラスです。 | '''CriticalSection'''クラスは、Windowsのクリティカルセクションをラップするクラスです。 | ||
クリティカルセクションは、スレッド間で同期を取るためのWin32オブジェクトの1つです。 | クリティカルセクションは、スレッド間で同期を取るためのWin32オブジェクトの1つです。 | ||
5行目: | 5行目: | ||
==クラスの機能== | ==クラスの機能== | ||
===継承するインタフェース=== | ===継承するインタフェース=== | ||
*[[ | *[[IDisposableインタフェース]] | ||
===メソッド=== | ===メソッド=== | ||
====コンストラクタ==== | ====コンストラクタ==== | ||
22行目: | 22行目: | ||
Function Enter() As CriticalSectionLock | Function Enter() As CriticalSectionLock | ||
;戻り値 | ;戻り値 | ||
:[[ | :[[CriticalSectionLockクラス]]のインスタンス | ||
このメソッドは、クリティカルセクションの所有権を得るまで待機します。 | このメソッドは、クリティカルセクションの所有権を得るまで待機します。 | ||
81行目: | 81行目: | ||
Sleep(-1) | Sleep(-1) | ||
</pre> | </pre> | ||
これを実行すると、例えば次のように出力されることがあります(常にこうなるとは限りません)。 | |||
abc | abc | ||
abc | abc | ||
162行目: | 162行目: | ||
de | de | ||
[[Category: | [[Category:ActiveBasic.Windows名前空間]] |
2007年8月5日 (日) 10:12時点における最新版
CriticalSectionクラスは、Windowsのクリティカルセクションをラップするクラスです。
クリティカルセクションは、スレッド間で同期を取るためのWin32オブジェクトの1つです。
クラスの機能
継承するインタフェース
メソッド
コンストラクタ
Sub CriticalSection()
デストラクタ
Sub ~CriticalSection()
Disposeを呼びます。
Dispose
クリティカルセクションオブジェクトを解放します。
Sub Dispose()
Enter
クリティカルセクションへ入ります。
Function Enter() As CriticalSectionLock
- 戻り値
- CriticalSectionLockクラスのインスタンス
このメソッドは、クリティカルセクションの所有権を得るまで待機します。
例
まずはクリティカルセクションを使用せず、データに異常を来たす例です。
#console #require <Classes/System/Threading/Thread.ab> '共有資源 Type StringData str[16] As TCHAR len As SIZE_T End Type Dim data As StringData Function TestProc(args As VoidPtr) As Long Do Dim buf[16] As TCHAR Dim i As Long Dim s = Nothing As String '異常を発生させやすくするため、わざと時間をかけて処理する With data For i = 0 To ELM(.len) buf[i] = .str[i] Sleep(60) Next s = New String(buf, .len As Long) End With Print s Sleep(0) Loop End Function Sub SetStringData(ByRef data As StringData) '出力文字列の変更 With data lstrcpy(.str, ToTCStr("de")) .len = lstrlen(.str) End With End Sub With data lstrcpy(.str, ToTCStr("abc")) .len = lstrlen(.str) End With Dim t As Thread(AddressOf(TestProc),0) t.Start() Sleep(1000) SetStringData(data) Sleep(-1)
これを実行すると、例えば次のように出力されることがあります(常にこうなるとは限りません)。
abc abc ae de de de
この場合では3行目の出力が異常なものになっています。これは、複数のスレッドが同時に変数strとlenを操作していることが原因です。
これをクリティカルセクションで保護すると次のようになります。
#console #require <Classes/System/Threading/Thread.ab> #require <Classes/ActiveBasic/Windows/CriticalSection.ab> '共有資源 Type StringData str[16] As TCHAR len As SIZE_T End Type Dim data As StringData Dim cs = New ActiveBasic.Windows.CriticalSection Function TestProc(args As VoidPtr) As Long Do Dim buf[16] As TCHAR Dim i As Long Dim s = Nothing As String Dim lock = cs.Enter With data For i = 0 To ELM(.len) buf[i] = .str[i] Sleep(60) Next s = New String(buf, .len As Long) End With lock.Leave() Print s Sleep(0) Loop End Function Sub SetStringData(ByRef data As StringData) Dim lock = cs.Enter With data lstrcpy(.str, ToTCStr("de")) .len = lstrlen(.str) End With lock.Leave() End Sub With data lstrcpy(.str, ToTCStr("abc")) .len = lstrlen(.str) End With Dim t As Thread(AddressOf(TestProc),0) t.Start() Sleep(1000) SetStringData(data) Sleep(-1)
今度は行単位でデータの整合性が取れた出力になっています。
abc abc abc de de de de de de