C ++: retornos de chamada e eventos do temporizador do sistema durante a cascata Destructor

StackOverflow https://stackoverflow.com/questions/4242879

Pergunta

Suponha um design de OO em que os objetos se chamam e, depois de um tempo, o retorno de chamada dos objetos dos objetos iniciantes (chamadas e retornos de chamada). Durante o término normal do programa, enquanto os destruidores são chamados, existe algum tipo de promessa de que nenhum temporizador do sistema será chamado e nenhum objeto iniciará um retorno de chamada?

Foi útil?

Solução

Há uma biblioteca incrível para lidar com esse tipo de chamadas e, é claro, é um impulso.

Ver Boost.signals2, com garantias de correção mesmo em aplicativo multithread :)

Nota em particular o uso de boost::trackable Classe, para que os objetos de destruição invalidem automaticamente as chamadas antes que elas aconteçam.

Nota: Boost.Signals (seu ancestral) tem praticamente a mesma funcionalidade, mas não é seguro para fios

Outras dicas

Não, não existe essa garantia.

Você precisa escrever seu código de modo que os objetos não sejam destruídos até terminar de usá -los.

  • O fracas de Boost pode ajudar a evitar o acesso a objetos destruídos de retornos de chamada em geral; portanto, provavelmente também durante o término. Ao usar isso, todos os objetos que precisam ser chamados de volta, precisam de um shared_ptr.
  • As funções de chamada/retornos de chamada dos temporizadores geralmente são bibliotecas de ponta, por isso depende se elas suportam uma funcionalidade StopallTimers (). Se você tem controle sobre a biblioteca, provavelmente não é muito difícil de implementar, mas ainda precisa saber quando acioná -la.

Não, não há promessa.

Existem duas maneiras de lidar com isso:

  • Tenha uma função de desregistro que um objeto pode chamar de destruição, o que garante que nenhum retorno de chamada será invocado depois que terminar - CancelAllCallbacks() ou similar.

  • Tenha um mecanismo de referência fraco, como o fraco_ptr que já foi mencionado, para invocar o retorno de chamada somente se uma referência forte foi obtida com sucesso.

Normalmente, a primeira opção é suficiente, a menos que os retornos de chamada possam ser agendados ou invocados de forma assíncrona - então você não tem uma maneira síncrona de impedir um retorno de chamada que já está programado para ser chamado, ou está de fato sendo chamado agora (ou algumas instruções de agora) em um fio diferente.

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