Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Os aplicativos multithreaded exigem um cuidado mais rigoroso do que os aplicativos single-threaded para garantir que as operações ocorram na ordem pretendida e que quaisquer dados acessados por vários threads não sejam corrompidos. Este tópico explica técnicas para evitar possíveis problemas ao programar aplicativos multithreaded com a biblioteca Microsoft Foundation Class (MFC).
Acessando objetos de vários threads
Os objetos MFC não são thread-safe por si só. Dois threads separados não podem manipular o mesmo objeto, a menos que você use as classes de sincronização MFC e/ou os objetos de sincronização Win32 apropriados, como seções críticas. Para obter mais informações sobre seções críticas e outros objetos relacionados, consulte Sincronização no SDK do Windows.
A biblioteca de classes usa seções críticas internamente para proteger estruturas de dados globais, como as usadas pela alocação de memória de depuração.
Acessando objetos MFC a partir de threads não-MFC
Se você tiver um aplicativo multithreaded que cria um thread de uma maneira diferente de usar um objeto CWinThread , você não pode acessar outros objetos MFC a partir desse thread. Em outras palavras, se você quiser acessar qualquer objeto MFC a partir de um thread secundário, deverá criar esse thread com um dos métodos descritos em Multithreading: Creating User-Interface Threads ou Multithreading: Creating Worker Threads. Esses métodos são os únicos que permitem que a biblioteca de classes inicialize as variáveis internas necessárias para lidar com aplicativos multithreaded.
Mapas de identificador do Windows
Como regra geral, um thread pode acessar apenas objetos MFC que ele criou. Isso ocorre porque os mapas de 'handle' temporários e permanentes do Windows são mantidos em armazenamento específico para threads para ajudar a manter a proteção contra o acesso simultâneo de vários threads. Por exemplo, um thread de trabalho não pode executar um cálculo e, em seguida, chamar a função membro de um documento UpdateAllViews para que as janelas que contêm vistas sobre os novos dados sejam modificadas. Isso não tem efeito algum, porque o mapa de CWnd objetos para HWNDs é local para o thread primário. Isso significa que um thread pode ter um mapeamento de um identificador do Windows para um objeto C++, mas outro thread pode mapear esse mesmo identificador para um objeto C++ diferente. As alterações feitas em um segmento não seriam refletidas no outro.
Existem várias formas de contornar este problema. A primeira é passar identificadores individuais (como um HWND) em vez de objetos C++ para o thread de trabalho. Em seguida, o thread de trabalho adiciona esses objetos ao seu mapa temporário chamando a função de membro apropriada FromHandle . Você também pode adicionar o objeto ao mapa permanente do thread chamando Attach, mas isso deve ser feito somente se você tiver a garantia de que o objeto existirá por mais tempo do que o thread.
Outro método é criar novas mensagens definidas pelo usuário correspondentes às diferentes tarefas que seus threads de trabalho executarão e postar essas mensagens na janela principal do aplicativo usando ::PostMessage. Este método de comunicação é semelhante a dois aplicativos diferentes conversando, exceto que ambos os threads estão sendo executados no mesmo espaço de endereço.
Para obter mais informações sobre como manipular mapas, consulte a Nota Técnica 3. Para obter mais informações sobre armazenamento local de thread, consulte Thread Local Storage e Using Thread Local Storage no Windows SDK.
Comunicação entre threads
MFC fornece várias classes que permitem que threads sincronizem o acesso a objetos para manter a segurança de threads. O uso dessas classes é descrito em Multithreading: Como Utilizar as Classes de Sincronização e Multithreading: Quando Utilizar as Classes de Sincronização. Para obter mais informações sobre esses objetos, consulte Sincronização no SDK do Windows.