質問

ミューテックスを使用してグローバルダブルを保護する例を実行していますが、エラーが発生します -

0x77B6308Eの未処理の例外 Lab7.exe:0xc0000005:アクセス違反 場所0x00000068を書く。

私はこれがスコアへのアクセスに関連していると思いますか? (グローバルダブル)

#include <windows.h>
#include <iostream>   
#include <process.h>

double score = 0.0; 


HANDLE threads[10];     

CRITICAL_SECTION score_mutex; 


unsigned int __stdcall MyThread(void *data)
{
    EnterCriticalSection(&score_mutex);
    score = score + 1.0; 
    LeaveCriticalSection(&score_mutex); 

    return 0;
}

int main()
{
    InitializeCriticalSection(&score_mutex); 

    for (int loop = 0; loop < 10; loop++)
    {

        threads[loop] = (HANDLE) _beginthreadex(NULL, 0, MyThread, NULL, 0, NULL); 
    }

    WaitForMultipleObjects(10, threads, 0, INFINITE); 

    DeleteCriticalSection(&score_mutex); 

    std::cout << score; 

    while(true);

}
.

更新:

ループを10の代わりに1000に設定した後、エラーはまだ発生したが、ミューテックスを参照してコードのコードをコメントアウトしたときにエラーは発生しませんでした。

CRITICAL_SECTION score_mutex; 
EnterCriticalSection(&score_mutex); 
LeaveCriticalSection(&score_mutex); 
InitializeCriticalSection(&score_mutex); 
DeleteCriticalSection(&score_mutex); 
.

アップデート2

スレッドは条約に従って0を返します(それは長い週でした!)

ミューテックス関連コードに戻して、CRITIAL_SECTION、InitializeCriticalSection、およびDeleteCriticalSectionを使用して、プログラムはコンパイルしてリースコンディションの問題(コースの2倍の競合問題の問題以外)を実行します。問題が表示されます。問題はEnterCriticalSectionまたはLeaveCriticalSectionを使用して、エラーがそれらを追加したときに再occurchを再実行してください。

役に立ちましたか?

解決

The remaining bug in your code is in the call to WaitForMultipleObjects(). You set the 3rd parameter to 0 (FALSE) such that the main thread unblocks as soon as any of the 10 threads finishes.

This causes the call to DeleteCriticalSection() to execute before all threads are finished, creating an access violation when one of the (possibly) 9 other threads starts and calls EnterCriticalSection().

他のヒント

You're writing beyond the end of your threads[10] array:

for (int loop = 0; loop < 1000; loop++){
     threads[loop];
}

threads only has size 10!

Your problem is that WaitForMultipleObjects is not waiting for all the threads to complete, causing the critical section to be prematurely deleted. According to MSDN, the third argument is

bWaitAll [in]

If this parameter is TRUE, the function returns when the state of all objects in the >lpHandles array is signaled. If FALSE, the function returns when the state of any one of >the objects is set to signaled. In the latter case, the return value indicates the object >whose state caused the function to return.

You set this to 0, which returns when ANY ONE of your threads completes. This causes the following DeleteCriticalSection to be run while there's still threads waiting to access it.

You should also declare score as a volatile so you don't have cached value problem.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top