Pergunta

Se você der uma olhada no clock_gettime () Função, disponível em todos os BSDs e é realmente definida como parte do padrão POSIX, você vê que há suporte para pelo menos três tipos de relógios (muitos sistemas suportam mais do que esses relógios, mas na verdade o padrão POSIX exige apenas um para um para estar presente, todos os outros são opcionais):

  • Clock_realTime - Posix exige que isso esteja presente. Este é o relógio de tempo da parede.

  • Clock_monotonic - Não faço ideia do que é isso (e o que significa SI Seconds), mas eu entendo que esse relógio nunca vai pular para trás, só pode aumentar monotonicamente em valor.

  • Clock_uptime - Não vejo como isso é diferente do Clock_monotonic (o tempo de atividade também nunca pula para trás), mas pelo menos sei que esse relógio começa em zero quando as botas do kernel (enquanto não se definirá qual o valor inicial Clock_monotonic terá quando as botas do kernel)

Vamos ignorar os outros relógios por um segundo. Clock_realTime não é garantido para contar monotonicamente para cima, certo? Este é o "tempo do sistema" real. Eu posso alterar o tempo do sistema à vontade. Eu posso defini -lo de 3 meses no passado ou 5 anos no futuro e cada vez que meu sistema sincroniza o tempo usando um servidor NTP na rede, o tempo pode saltar para frente ou para trás.

Agora temos duas funções de sono em um sistema BSD. dorme() e nanosleep (). Não tenho certeza, mas esperaria que o Sleep () fosse implementado no topo da Nanosleep, afinal, posso imitar facilmente o Sleep () usando Nanosleep () e definir apenas o número de segundos no times struct, mantendo os nanossegundos zero zero .

Eu li em muitas fontes, que essas funções realmente funcionam calculando o tempo de despertar (obtenha o horário atual, adicione o valor do sono) e o sistema verá o intervalo regular se a hora atual for mais tarde do que o tempo de despertar e, se assim for, ele acordará o tópico novamente. O fato de que isso é verificado apenas em intervalos é a razão pela qual as páginas do homem dizem que o sono atual dormirá por pelo menos esse período de tempo (mais curto apenas se interrompido por um sinal), mas pode dormir mais (dependendo da frequência com que frequência O sistema verifica se já estamos passando pelo tempo de despertar e dependendo de quanto tempo leva para que o agendador permita que esse thread seja executado novamente).

Tudo isso é perfeitamente sensato para mim ... mas há uma pergunta que sempre me incomodava:

De acordo com várias fontes, o sono (pelo menos o Nanosleep) usa Clock_realtime como relógio internamente. Isso significa que, se informar a Nanosleep () para dormir por 30 segundos e depois alterar meu relógio do sistema para 1 hora no futuro, o tópico acordará quase imediatamente (1 hora no futuro está muito à frente do nanoesleep de tempo de despertar ( ) calculado). Isso também está perfeitamente bem. No entanto O que acontece se eu dizer acordar em 30 segundos e o usuário descobrir que o relógio do sistema está uma hora à frente e coloca o relógio para trás em uma hora? Então meu tópico vai dormir por 1 hora e 30 segundos? Pois isso seria bastante ruim.

Foi útil?

Solução

Até onde eu sei, as funções do sono geralmente são implementadas mais como um contador decrescente. Você diz "Dormir por 10 segundos", que se traduz em "Sleep for 1000 Schedule Ticks" no agendador e, toda vez que o agendador verifica nos processos de dormir, diminui a quantidade de tempo restante.

Dessa forma, o tempo de sono sempre será uma quantidade de tempo real para dormir, em vez de dormir até algum tempo no futuro. A razão para isso é como você suspeitou, se escolhermos um tempo no futuro, talvez nunca chegássemos lá (ou chegarmos lá em um período inesperado de tempo). Isso é consistente com o que você deseja usar o sono em um programa. Não é para fazer cálculos semelhantes a calendários.

Você também pode fazer um teste simples, fazer um programa dormir por 30 segundos, usar o comando nix "time" com o tempo, quanto tempo a função funciona e, depois de começar a alterar o relógio do sistema 5 minutos e ver o que acontece.

Outras dicas

O segmento estará checando em um contador interno que é definido na duração do sono não no ponto final do sono. O contador interno usado não tem nada a ver com o tempo atual do sistema e, portanto, não será afetado se houver alguma alteração no tempo do sistema.

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