Domanda

Sto lavorando attraverso un esempio di proteggere un doppio globale usando i mutasi, tuttavia ottengo l'errore -

.

Eccezione non gestita a 0x77b6308e in Lab7.exe: 0xc0000005: violazione di accesso Scrittura posizione 0x00000068.

Suppongo che questo sia legato all'accesso al punteggio? (Il doppio globale)

#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);

}
.

Aggiornamento:

Dopo aver fissato il problema con il ciclo impostato su 1000 invece di 10, l'errore è stato ancora accaduto, tuttavia quando ho commentato i pezzi di codice che si riferiscono al mutex che l'errore non si è verificato.

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

Aggiorna 2

I thread ritornano 0 come da convenzione (è stata una lunga settimana!)

Ho provato ad aggiungere il codice relativo al mutex e il programma compilerà ed eseguirà bene (diverso dai problemi di condizione di gara con il doppio ovviamente) con criticità_sezione, inizializzazione e delitecriticità di ritorno. Il problema appare a essere con entercriticality oavecriticante, poiché l'errore rirresca quando li aggiungo.

È stato utile?

Soluzione

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().

Altri suggerimenti

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top