Question

Je travaille à travers un exemple de protection d'un double global à l'aide de mutexes, mais j'obtiens l'erreur -

Exception non perdue à 0x77b6308e dans Lab7.exe: 0xc0000005: Emplacement d'écriture de violation d'accès 0x00000068.

Je suppose que cela est lié à l'accès au score? (Le double mondial)

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

}

Mise à jour:

Après avoir résolu le problème avec la boucle définie sur 1000 au lieu de 10, l'erreur s'est toujours produite, mais lorsque j'ai commenté les pièces de code se référant au mutex, l'erreur ne s'est pas produite.

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

MISE À JOUR 2

Les fils retournent 0 selon la convention (ça a été une longue semaine!)

J'ai essayé de ajouter dans le code lié à Mutex, et le programme se compile et fonctionnera bien (autre que les problèmes de condition de course avec le double bien sûr) avec Critics_Section, InitializeccriticalSection et DeleteCriticalSection tous ajoutés. Le problème semble être avec EnterCriticalSection ou LeaveccriticalSection, comme l'erreur se reproduit lorsque je les ajoute.

Était-ce utile?

La solution

Le bogue restant de votre code est dans l'appel à WaitForMultipleObjects(). Vous définissez le 3ème paramètre sur 0 (FALSE) de sorte que le fil principal débloque dès que n'importe quel des 10 finitions.

Cela provoque l'appel à DeleteCriticalSection() Pour exécuter avant la fin de tous les threads, créant une violation d'accès lorsque l'un des (éventuellement) 9 autres threads démarre et appelle EnterCriticalSection().

Autres conseils

Vous écrivez au-delà de la fin de votre threads[10] déployer:

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

threads a seulement la taille 10!

Votre problème est que WaitFormultipleObjects n'attend pas que tous les fils se terminent, ce qui entraîne la suppression prématurément de la section critique. Selon MSDN, le troisième argument est

Bwaitall [in

Si ce paramètre est vrai, la fonction renvoie lorsque l'état de tous les objets du tableau> lphandles est signalé. Si faux, la fonction revient lorsque l'état de l'un des> les objets est défini sur signalé. Dans ce dernier cas, la valeur de retour indique l'objet> dont l'état a fait revenir la fonction.

Vous le définissez sur 0, ce qui revient lorsque l'un de vos fils termine. Cela entraîne l'exécution de la vente de désécision suivante alors qu'il y a encore des threads en attente pour y accéder.

Vous devez également déclarer le score comme un volatil afin que vous n'ayez pas de problème de valeur mis en cache.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top