Pergunta

Estou trabalhando em um exemplo de proteção de um duplo global usando mutexes, mas recebo o erro -

Exceção não atendida em 0x77b6308e em lab7.exe:0xC0000005:Acesso Local de Redação de Violação 0x00000068.

Presumo que isso esteja relacionado ao acesso à pontuação.(O duplo global)

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

}

Atualizar:

Depois de corrigir o problema com o loop sendo definido como 1000 em vez de 10, o erro ainda ocorreu, porém quando comentei os trechos de código referentes ao mutex o erro não ocorreu.

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

Atualização 2

Os tópicos retornam 0 conforme a convenção (foi uma semana longa!)

Tentei adicionar novamente o código relacionado ao mutex, e o programa irá compilar e funcionar bem (exceto os problemas de condição de corrida com o dobro, é claro) com CRITICAL_SECTION, InitializeCriticalSection e DeleteCriticalSection, todos adicionados novamente.O problema parece ser com EnterCriticalSection ou LeaveCriticalSection, pois o erro ocorre novamente quando eu os adiciono.

Foi útil?

Solução

O bug restante no seu código está na chamada para WaitForMultipleObjects().Você define o terceiro parâmetro como 0 (FALSE) de modo que o thread principal seja desbloqueado assim que qualquer dos 10 fios termina.

Isso faz com que a chamada seja DeleteCriticalSection() para ser executado antes que todos os threads sejam concluídos, criando uma violação de acesso quando um dos (possivelmente) 9 outros threads inicia e chama EnterCriticalSection().

Outras dicas

Você está escrevendo além do final do seu threads[10] variedade:

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

threads só tem tamanho 10!

Seu problema é que WaitForMultipleObjects não está aguardando a conclusão de todos os threads, fazendo com que a seção crítica seja excluída prematuramente.De acordo com MSDN, o terceiro argumento é

bEspere tudo [in]

Se este parâmetro for TRUE, a função retorna quando o estado de todos os objetos do array >lpHandles for sinalizado.Se for FALSO, a função retornará quando o estado de qualquer um dos objetos for definido como sinalizado.Neste último caso, o valor de retorno indica o objeto cujo estado causou o retorno da função.

Você define isso como 0, que retorna quando QUALQUER UM dos seus threads é concluído.Isso faz com que o seguinte DeleteCriticalSection seja executado enquanto ainda há threads aguardando para acessá-lo.

Você também deve declarar a pontuação como volátil para não ter problemas de valor em cache.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top