Qual é a melhor maneira de sair de um loop após um tempo decorrido de 30ms em C ++

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

  •  09-09-2019
  •  | 
  •  

Pergunta

O que é a melhor maneira de sair de um laço tão perto de 30ms quanto possível em C ++. boost Polling: microsec_clock? Polling QTime? Outra coisa?

Algo como:

A = now;
for (blah; blah; blah) {
    Blah();
    if (now - A > 30000)
         break;
}

Ele deve funcionar em Linux, OS X e Windows.

Os cálculos no circuito são para atualizar uma simulação. A cada 30ms, eu gostaria de atualizar a janela.

Foi útil?

Solução

O exemplo trecho de código em este link praticamente faz o que quiser:

http://www.cplusplus.com/reference/clibrary/ctime/ relógio /

Adaptado de seu exemplo:

void runwait ( int seconds )
{
   clock_t endwait;
   endwait = clock () + seconds * CLOCKS_PER_SEC ;
   while (clock() < endwait)
   {
      /* Do stuff while waiting */
   }
}

Outras dicas

Os cálculos no circuito são para atualizando uma simulação. A cada 30ms, eu como para atualizar a janela.

Você considerou usando threads? O que você descreve parece ser o exemplo perfeito de por que você deve usar threads em vez de temporizadores.

O principal segmento do processo continua cuidando da UI, e ter um conjunto QTimer a 30ms para atualizá-lo. Ele bloqueia um QMutex para ter acesso aos dados, executa a atualização e libera o mutex.

O segundo segmento (ver QThread ) faz a simulação. Para cada ciclo, ele bloqueia o QMutex, faz os cálculos e liberta a extensão mútua quando os dados estão num estado estável (adequado para a actualização de UI).

Com a crescente tendência em processadores multi-core, você deve pensar mais e mais sobre o uso de tópicos do que sobre o uso de temporizadores. Suas aplicações automaticamente benefícios do aumento de potência (vários núcleos) de novos processadores.

Enquanto isso não responder à pergunta, pode dar um outro olhar para a solução. Que tal colocar o código de simulação e interface de usuário em diferentes segmentos? Se você usar o Qt, atualização periódica pode ser realizado utilizando um temporizador ou mesmo QThread :: msleep ( ) . Você pode adaptar o rosca Mandelbrot exemplo para atender sua necessidade.

Se você precisa fazer o trabalho até um certo tempo tenha decorrido, em seguida, resposta do docflabby é spot-on. No entanto, se você só precisa esperar, sem fazer nada, até um tempo especificado tiver decorrido, então você deve usar usleep()

A resposta curta é:. Você não pode, em geral, mas você pode se você estiver executando no sistema operacional direita ou sobre o hardware certo

Você pode chegar perto de 30ms em todo o sistema operacional da usando uma chamada de montagem em sistemas Intel e algo mais em outras arquiteturas. Eu vou cavar o de referência e editar a resposta para incluir o código quando eu encontrá-lo.

O problema é o algoritmo de time-slicing e como perto do fim de sua fatia de tempo você está em um multi-tasking OS.

Em alguns real-time OS de, há uma chamada de sistema em uma biblioteca de sistema você pode fazer, mas eu não tenho certeza do que essa chamada seria.

edit: LOL! Alguém já postou um trecho semelhante no SO: função de temporizador para fornecer tempo em nano segundos usando C ++

VonC tem o comentário com o código de montagem temporizador CPU na mesma.

De acordo com a sua pergunta, a cada 30ms que você gostaria de atualizar a janela. Eu escrevi um aplicativo semelhante, uma vez que o hardware apalpada cada 500ms para o material similar. Enquanto isso não responder diretamente sua pergunta, eu tenho as seguintes followups:

  • Você tem certeza que Blah (), para atualizar o visor, pode executar em menos de 30ms em todos os casos?
  • parece mais como correr Blah () seria feito melhor por um callback timer.
  • É muito difícil encontrar um objeto timer biblioteca que vai empurrar em um intervalo para fazer alterações em uma estrutura gráfica 30ms. No Windows XP, descobri que o temporizador padrão API Win32 que mensagens de janela empurra sobre temporizador de expiração do intervalo, mesmo em um 2GHz P4, não podia fazer atualizações mais rápido do que 300ms de intervalo, não importa o quão baixo eu definir o intervalo de tempo para a cronômetro. Embora houvesse temporizadores de alto desempenho disponíveis na API Win32, eles têm muitas restrições, ou seja, que você não pode fazer qualquer IPC (como widgets de UI Update) em um loop como o que você citou acima.
  • Basicamente, o resultado é que você tem que planejar com muito cuidado como você deseja ter atualizações ocorrem. Você pode precisar usar tópicos, e olhada em como você deseja atualizar a janela.

Apenas algumas coisas em que pensar. Eles me pegou de surpresa quando eu trabalhava no meu projeto. Se você já pensou essas coisas por meio já, por favor desconsidere a minha resposta:. 0)

Você pode considerar apenas atualizar a janela cada simulação N passos em vez da cada milissegundos K. Se esta é (digamos) um aplicativo comercial séria, então você provavelmente vai querer ir a rota multi-thread sugeriu em outro lugar, mas se (por exemplo) é para uso pessoal ou limitado público e que você está realmente interessado em é os detalhes de tudo o que você está simulando, em seguida, a cada-N-passos é simples, portátil e pode muito bem ser bom o suficiente para estar ficando com.

Veja QueryPerformanceCounter e QueryPerformanceFrequency

Se você estiver usando Qt, aqui é uma maneira simples de fazer isso:

QTimer* t = new QTimer( parent ) ;
t->setInterval( 30 ) ; // in msec
t->setSingleShot( false ) ;
connect( t, SIGNAL( timeout() ), viewPort, SLOT( redraw() ) ) ;

Você vai precisar especificar viewPort e redraw(). Em seguida, iniciar o temporizador com t->start().

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