私はvb6マルチスレッドアプリケーションを動作させています。データを保護するためにmutexを使用したいと思います。期待される振る舞いは、スレッドが既存のミューテックスのロックを取得しようとしたときに、「WaitForSingleObject」関数が呼び出されたときにそのスレッドがミューテックスが通知されるまでブロックすることです。私が経験しているのは、アプリケーション全体がフリーズすることです。マルチスレッドを使用しているときにアプリケーション全体をフリーズする
私のプロジェクトを複製するには、VB6を開き、新しいActive X EXEを作成します。デフォルトの名前でモジュールを作成します。これでこのコードを配置します。
Option Explicit
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Sub Main()
' this hack is necessary to ensure that we only 'create' the application window once..
Dim hwnd As Long
hwnd = FindWindow(vbNullString, "Form1")
If hwnd = 0 Then
Dim f As Form1
Set f = New Form1
f.Show
Set f = Nothing
End If
End Sub
次は、デフォルトの名前で、クラスを作成し、それにこのコードを追加します。
Option Explicit
Private Const INFINITE = -1&
Private Const STANDARD_RIGHTS_REQUIRED As Long = &HF0000
Private Const SYNCHRONIZE As Long = &H100000
Private Const MUTANT_QUERY_STATE As Long = &H1
Private Const MUTANT_ALL_ACCESS As Long = (STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or MUTANT_QUERY_STATE)
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Declare Function CreateMutex Lib "kernel32" Alias "CreateMutexA" (lpMutexAttributes As Any, ByVal bInitialOwner As Long, ByVal lpName As String) As Long
Private Declare Function OpenMutex Lib "kernel32" Alias "OpenMutexA" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal lpName As String) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function ReleaseMutex Lib "kernel32" (ByVal hMutex As Long) As Long
Private Const MUTEX_NAME As String = "mymutex"
Private m_hCurrentMutex As Long
Public Sub Class_Terminate()
Call ReleaseIt
End Sub
Public Sub LockIt(success As String)
Dim hMutex As Long
MsgBox "Lockit t:" & App.ThreadID
hMutex = OpenMutex(STANDARD_RIGHTS_REQUIRED, 0, MUTEX_NAME)
If hMutex <> 0 Then
Form1.Caption = "waiting on mutex"
MsgBox "waiting t:" & App.ThreadID
Dim res As Long
Do
'MsgWaitForMultipleObjects
res = WaitForSingleObject(hMutex, INFINITE)
DoEvents
Loop While res = -1
m_hCurrentMutex = hMutex
Else
Form1.Caption = "creating mutex"
m_hCurrentMutex = CreateMutex(ByVal 0&, 1, MUTEX_NAME)
End If
Form1.Caption = success
MsgBox success
End Sub
Public Sub ReleaseIt()
If m_hCurrentMutex <> 0 Then
Call ReleaseMutex(m_hCurrentMutex)
Call CloseHandle(m_hCurrentMutex)
m_hCurrentMutex = 0
End If
End Sub
最後に、メインフォームで、4つのコマンドボタンと、このコードを追加します。
Option Explicit
Dim c(1) As Class1
'Lock
Private Sub Command1_Click()
If c(0) Is Nothing Then Set c(0) = CreateObject("Project1.Class1")
Call c(0).LockIt("Object0")
End Sub
Private Sub Command2_Click()
If c(1) Is Nothing Then Set c(1) = CreateObject("Project1.Class1")
Call c(1).LockIt("Object1")
End Sub
'Free
Private Sub Command3_Click()
If c(0) Is Nothing Then Set c(0) = CreateObject("Project1.Class1")
Call c(0).ReleaseIt
End Sub
Private Sub Command4_Click()
If c(1) Is Nothing Then Set c(1) = CreateObject("Project1.Class1")
Call c(1).ReleaseIt
End Sub
Private Sub Form_Unload(Cancel As Integer)
Set c(0) = Nothing
Set c(1) = Nothing
End
End Sub
最初の2つのコマンドボタンはそれぞれのミューテックスをロックします。 2番目の2つは無料です。ミューテックスがロックされる前に、一意のスレッドIDが表示されることに注意してください。これにより、そのスレッドだけがブロックされ、アプリケーション全体がフリーズしないと信じられました。
ご協力いただければ幸いです。ありがとうございました。
編集:私は非常に重要な部分を忘れていました:プロジェクトのプロパティセクションでは、私はそれがオブジェクトごとのスレッドを作成するように設定しており、これはmsghox App.ThreadID呼び出しの結果で検証されます。
Ahh-私は非常に重要な部分について言及するのを忘れていました:プロジェクトプロパティのセクションで、私はそれを 'オブジェクトごとのスレッド'を作成するように設定しました。これはmsghox App.ThreadID呼び出しの結果で検証されます。同じミューテックス名を使用することに関しては、私が保護する必要がある様々な変数があるため、これは必要です。このデモアプリケーションでは、実際に何も保護されていませんが、アプリケーションでは共有変数/メモリの名前としてmutex名を使用していますので、mutexを使用していても別のスレッドのmutexをフリーズしませんそれは異なるミューテックスである限り長い。 –
@AuthmanApatiraは、アプリケーションがブロックする(VB6がインストールされていない)ときに説明してください。 –
私は最初のロックボタンをクリックして、スレッドID、待機中、次に文字列iが(object0)で渡され、mutexを正常に取得したことを警告します。 2番目のロックボタンをクリックすると、別のユニークなスレッドIDを待っています---待ってからゲームオーバーします。私がdowhileループをコメントアウトしてwaitforsingleobject行を残すと、-1が返され(失敗)、すぐに関数の処理が続行されます。 doeventsは実際に助けて/何もしていません。私は考えていたのは、新しいスレッド、多分ウィンドウのmsgsを処理する必要があるため、msgwait行だが、イオノ –