Pergunta

Eu tenho um aplicativo C ++ multithread que faz renderização em 3D com a biblioteca OpenSceneGraph. Estou planejando iniciar o loop de renderização da OSG como um thread separado usando o boost :: threads, passando uma estrutura de dados contendo estado compartilhado para o thread. Estou tentando evitar algo muito pesado (como mutexes) para sincronização, pois o loop de renderização precisa ser bem apertado, e o próprio OSG tenta evitar ter que travar. A maior parte do estado compartilhado é definido antes do início do tópico e nunca alterado. Eu tenho alguns dados que precisam ser alterados, que estou planejando dobrar duas vezes. No entanto, tenho um simples booleano para sinalizar o fio para suspender a renderização e depois retomar a renderização e outra para matá -la. Nos dois casos, o encadeamento do aplicativo define o bool e o thread de renderização apenas o lê. Preciso sincronizar o acesso a essas bools? Até onde eu sei, a pior coisa que poderia acontecer é o loop de renderização continua para um quadro extra antes de suspender ou desistir.

Foi útil?

Solução

Em C ++ 11 e posterior, que possui simultaneidade definida por padrões, use std::atomic<bool> para esse fim. A partir de http://en.cppreference.com/w/cpp/atomic/atomic:

Se um thread gravar em um objeto atômico enquanto outro thread lê, o comportamento será bem definido (consulte o modelo de memória para obter detalhes nas corridas de dados).


A seguinte resposta antiga pode ter sido verdadeira em algum momento no passado com alguns compiladores e alguns ambientes operacionais, mas não deve ser invocado hoje:

Você está certo, neste caso, você não precisará sincronizar os bools. Você deve declará -los volatile No entanto, para garantir que o compilador realmente os leia da memória a cada vez, em vez de armazenar em cache a leitura anterior em um thread (essa é uma explicação simplificada, mas deve fazer para esse fim).

A pergunta seguinte tem mais informações sobre isso: Tópico C ++, dados compartilhados

Outras dicas

Por que não simplesmente usar um variável interligada?

Quanto ao C ++ 11 e posteriormente, finalmente é consciente de threads e afirma claramente que modificar um bool (ou outra variável não atômica) em um encadeamento e acessar-o ao mesmo tempo em outro é um comportamento indefinido. No seu caso usando std::atomic<bool> deve ser suficiente para corrigir seu programa, economizando você de usar bloqueios.
Não use volatile. Não tem nada a ver com threads. Para mais discussões, veja Posso ler uma variável bool em um thread sem mutex?

Eu não acho que você precisar Um mutex totalmente completo aqui - embora o thread de renderização precise esperar o estado 'suspenso' se você não estiver usando um objeto de sincronização que suporta uma espera primitiva.

Você deve usar o uso das várias primitivas de troca entrelaçadas (interlockedExchange no Windows). Não porque a leitura/grava do bool não seja atômica, mas para garantir que não haja comportamentos estranhos, o compilador reordenando a memória acessos em um único encadeamento.

Este tópico tem um pouco mais de informação e discussão sobre segurança, especialmente para tipos de dados simples:

Como posso criar um padrão de singleton seguro para threads no Windows?

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