Escrever um programa Win32 multithread
Quando você escreve um programa com vários segmentos, você deve coordenar seu comportamento e uso dos recursos do programa de.Você também deve certificar-se de que cada thread recebe sua própria pilha.
Compartilhamento de recursos comuns entre Threads
Observação |
---|
Para uma discussão semelhante do ponto de vista do MFC, consulte Multithreading: Dicas de programação e Multithreading: Quando usar as Classes de sincronização. |
Cada segmento possui sua própria pilha e registra sua própria cópia da CPU.Outros recursos, como arquivos, dados estáticos e memória heap, são compartilhados por todos os segmentos no processo.Segmentos usando esses recursos comuns devem ser sincronizados.Win32 fornece várias maneiras para sincronizar os recursos, incluindo semáforos, as seções críticas, eventos e exclusões mútuas.
Quando vários segmentos estão acessando dados estáticos, o programa deve fornecer para conflitos de recursos possível.Considere um programa onde um thread atualiza uma estrutura de dados estáticos que contém x,y coordenadas para itens a serem exibidos por outro thread.Se o thread de atualização altera o x coordenar e é superado antes que possa alterar a y coordenada, o thread de exibição pode ser agendado antes do y coordenada é atualizada.O item seria exibido no local errado.Você pode evitar esse problema usando semáforos para controlar o acesso à estrutura.
Um mutex (abreviação de mutual exconclusão) é uma forma de comunicação entre segmentos ou processos que estão executando assincronamente um do outro.Essa comunicação é geralmente usada para coordenar as atividades de vários segmentos ou processos, geralmente controlando o acesso a um recurso compartilhado, bloqueio e desbloqueio do recurso.Para solucionar esse problema x,y problema atualização coordenada, o thread de atualização define um mutex indicando que a estrutura de dados está em uso antes de executar a atualização.Seria claro o mutex depois ambas as coordenadas tinham sido processadas.O thread de exibição deve aguardar o mutex de ser criptografado antes de atualizar a exibição.Esse processo de esperando um mutex geralmente é chamado de bloqueio em um mutex porque o processo é bloqueado e não pode continuar até que o mutex limpa.
O programa de Bounce.c mostrado na Programa de exemplo Multithread C usa um mutex nomeado ScreenMutex para coordenar as atualizações de tela.Cada vez que um dos segmentos de vídeo está pronto para escrever na tela, ele chama WaitForSingleObject com a alça para ScreenMutex e constante INFINITA para indicar que o WaitForSingleObject chamada deve bloquear o mutex e não o tempo limite.Se ScreenMutex é claro, a função espera define o mutex para que outros segmentos não podem interferir com a exibição e continua executando o thread.Caso contrário, o thread bloqueia até que o mutex limpa.Quando o thread concluir a atualização de vídeo, ele libera o mutex chamando ReleaseMutex.
Tela exibe e dados estáticos são apenas dois dos recursos que requerem gerenciamento cuidadoso.Por exemplo, o programa pode ter vários segmentos acessando o mesmo arquivo.Porque outro thread pode ter movido o ponteiro do arquivo, cada segmento deve redefinir o ponteiro do arquivo antes de ler ou escrever.Além disso, cada thread deve certificar-se de que não é superado entre o momento em que ele posiciona o ponteiro e o tempo que acessa o arquivo.Esses threads devem usar um semáforo para coordenar o acesso ao arquivo pelo cercando cada acesso de arquivo com WaitForSingleObject e ReleaseMutex chamadas.O exemplo de código a seguir ilustra essa técnica:
HANDLE hIOMutex= CreateMutex (NULL, FALSE, NULL);
WaitForSingleObject( hIOMutex, INFINITE );
fseek( fp, desired_position, 0L );
fwrite( data, sizeof( data ), 1, fp );
ReleaseMutex( hIOMutex);
Pilhas de thread
Todo espaço de pilha padrão do aplicativo é alocada para o primeiro thread de execução, que é conhecido como thread 1.Como resultado, você deve especificar a quantidade de memória para alocar para uma pilha separada para cada segmento adicional seu programa precisa.O sistema operacional aloca espaço de pilha adicionais para o thread, se necessário, mas você deve especificar um valor padrão.
O primeiro argumento do _beginthread chamada é um ponteiro para o BounceProc função, que executa os threads.O segundo argumento especifica o tamanho de pilha padrão para o segmento.O último argumento é um número de identificação é passado para BounceProc.BounceProc usa o número de identificação para propagar o gerador de números aleatórios para selecionar o atributo de cor do segmento e exibir caracteres.
Segmentos que fazem chamadas para a biblioteca de tempo de execução c ou a API do Win32 devem permitir espaço de pilha suficiente para a biblioteca e chamam funções da API.C printf função requer mais de 500 bytes de espaço de pilha e você deve ter 2 K de espaço de pilha disponível ao chamar as rotinas API do Win32.
Como cada thread possui sua própria pilha, você pode evitar possíveis colisões sobre itens de dados, usando como dados estáticos pequeno quanto possível.Design de seu programa para usar variáveis de pilha automático para todos os dados podem ser particulares a um thread.As variáveis globais somente no programa de Bounce.c são exclusões mútuas ou variáveis que nunca alterar após eles são inicializados.
Win32 também fornece armazenamento Thread Local (TLS) para armazenar dados por thread.Para mais informações, consulte Armazenamento Local de thread (TLS).