「CriticalSectionクラス」の版間の差分

提供: AB開発Wiki
ナビゲーションに移動検索に移動
(Win32クリティカルセクションのラッパクラス)
 
(ページ CriticalSection クラスCriticalSectionクラス へ移動: #127)
 
(同じ利用者による、間の1版が非表示)
1行目: 1行目:
'''CriticalSection''' クラスは、Windowsのクリティカルセクションをラップするクラスです。
+
'''CriticalSection'''クラスは、Windowsのクリティカルセクションをラップするクラスです。
  
 
クリティカルセクションは、スレッド間で同期を取るためのWin32オブジェクトの1つです。
 
クリティカルセクションは、スレッド間で同期を取るためのWin32オブジェクトの1つです。
5行目: 5行目:
 
==クラスの機能==
 
==クラスの機能==
 
===継承するインタフェース===
 
===継承するインタフェース===
*[[IDisposable]] インタフェース
+
*[[IDisposableインタフェース]]
 
===メソッド===
 
===メソッド===
 
====コンストラクタ====
 
====コンストラクタ====
22行目: 22行目:
 
  Function Enter() As CriticalSectionLock
 
  Function Enter() As CriticalSectionLock
 
;戻り値
 
;戻り値
:[[CriticalSectionLock クラス]]のインスタンス
+
:[[CriticalSectionLockクラス]]のインスタンス
 
このメソッドは、クリティカルセクションの所有権を得るまで待機します。
 
このメソッドは、クリティカルセクションの所有権を得るまで待機します。
  
81行目: 81行目:
 
Sleep(-1)
 
Sleep(-1)
 
</pre>
 
</pre>
これを実行すると、例えば次のように出力されることがあります。
+
これを実行すると、例えば次のように出力されることがあります(常にこうなるとは限りません)。
 
  abc
 
  abc
 
  abc
 
  abc
162行目: 162行目:
 
  de
 
  de
  
[[Category:Windows 名前空間]]
+
[[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