Diferenças
Aqui você vê as diferenças entre duas revisões dessa página.
Ambos lados da revisão anterior Revisão anterior | |||
pua:gerencia_de_tempo [2023/09/01 15:57] – [Gestão do tempo] maziero | pua:gerencia_de_tempo [2023/09/01 15:58] (atual) – [Relógios no Linux] maziero | ||
---|---|---|---|
Linha 1: | Linha 1: | ||
+ | ====== Gestão do tempo ====== | ||
+ | |||
+ | Este módulo trata dos aspectos de programação relacionados à gestão do tempo em um ambiente UNIX. Os seguintes tópicos são abordados: | ||
+ | |||
+ | * referências de tempo | ||
+ | * tempo absoluto | ||
+ | * funções de calendário | ||
+ | * o relógio do sistema | ||
+ | * temporizadores | ||
+ | * esperas | ||
+ | |||
+ | Antes de iniciar, é importante definir corretamente alguns termos relacionados a tempo: | ||
+ | |||
+ | * **Tempo absoluto** (//calendar time//) é um instante preciso na referência de tempo universal, como 18/10/2004, 14: | ||
+ | * **Intervalo** é uma parte contínua de tempo entre dois tempos absolutos. Um exemplo seria o intervalo de 13:30:00 a 17:50:00 do dia 18/10/2004. | ||
+ | * **Tempo decorrido** (//elapsed time//) é o tamanho de um intervalo. No exemplo acima, o tempo decorrido seria de 4:20:00. | ||
+ | * A **duração** (//amount of time//) é a soma dos tempos decorridos em todos os intervalos considerados. Por exemplo, a duração de nosso curso é de 60 horas, distribuídas entre vários intervalos. | ||
+ | * O **período** é o tempo decorrido no intervalo entre dois eventos, considerado sobretudo quando esses eventos são parte de uma seqüência de eventos repetitivos. | ||
+ | * O **tempo de CPU** (//CPU time//) é similar ao tempo absoluto, mas considerado para cada processo em particular. | ||
+ | * O **tempo de processamento** (// | ||
+ | |||
+ | ===== Relógios no Linux ===== | ||
+ | |||
+ | |||
+ | Um sistema Linux possui dois relógios: o **relógio de hardware** e o **relógio do sistema**. | ||
+ | |||
+ | O //relógio de hardware// avança sem interferência do sistema operacional, | ||
+ | |||
+ | O //relógio do sistema// é um valor de tempo mantido pelo núcleo do sistema operacional. Ele é inicializado com o valor do RTC durante a carga do sistema e mantido atualizado através de interrupções de tempo geradas pelo hardware. O RTC não é consultado frequentemente durante a vida ativa do sistema. | ||
+ | |||
+ | ===== Tempo absoluto ===== | ||
+ | |||
+ | |||
+ | Várias funções permitem consultar/ | ||
+ | ==== Tempo absoluto simples ==== | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | time_t time (time_t *result) | ||
+ | int stime (time_t *newtime) | ||
+ | </ | ||
+ | |||
+ | Estas funções permitem consultar ou ajustar o tempo absoluto do sistema com uma granularidade de segundos. O tipo '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | double difftime (time_t time1, time_t time0) | ||
+ | </ | ||
+ | |||
+ | Retorna o número de segundos decorridos entre os dois tempos absolutos informados. Essa é a única forma portável de fazer esse cálculo, pois a implementação do tipo '' | ||
+ | |||
+ | Um pequeno exemplo do uso das funções '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | |||
+ | int main (int argc, char * argv[]) | ||
+ | { | ||
+ | | ||
+ | | ||
+ | | ||
+ | sleep (5) ; | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Tempo absoluto preciso ==== | ||
+ | |||
+ | |||
+ | As funções abaixo indicadas permitem obter/ | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | int gettimeofday (struct timeval *tp, struct timezone *tzp) | ||
+ | int settimeofday (const struct timeval *tp, const struct timezone *tzp) | ||
+ | </ | ||
+ | |||
+ | Estas funções permitem informar ou ajustar o tempo absoluto do sistema (desde //epoch//). O tempo é representado pela estrutura '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | struct timeval | ||
+ | { | ||
+ | long int tv_sec | ||
+ | long int tv_usec ; // micro-segundos decorridos (valor mínimo depende do sistema) | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | O fuso horário local é informado através do '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | int adjtime (const struct timeval *delta, struct timeval *olddelta) | ||
+ | </ | ||
+ | |||
+ | Ajustar abruptamente o relógio do sistema gera descontinuidades que podem interferir no funcionamento de vários processos. Esta função permite acelerar ou retardar o relógio do sistema gradualmente para fazer o ajuste indicado por '' | ||
+ | |||
+ | Um pequeno exemplo do uso da função '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | | ||
+ | int main (int argc, char * argv[]) | ||
+ | { | ||
+ | | ||
+ | float delta ; | ||
+ | | ||
+ | | ||
+ | sleep (2) ; | ||
+ | | ||
+ | | ||
+ | delta = (depois.tv_sec + depois.tv_usec/ | ||
+ | | ||
+ | | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== Datas ===== | ||
+ | |||
+ | Os tempos reportados pelas funções acima são úteis para computações, | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | struct tm * localtime (const time_t *time) | ||
+ | </ | ||
+ | |||
+ | Converte o tempo informato em time em uma estrutura '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | struct tm | ||
+ | { | ||
+ | int tm_sec ; | ||
+ | int tm_min ; | ||
+ | int tm_hour ; horas (0..23) | ||
+ | int tm_mday ; dia do mês (1..31) | ||
+ | int tm_mon ; mês do ano (0..11) | ||
+ | int tm_year ; ano (com dois dígitos, contado a partir de 1900) | ||
+ | int tm_wday ; dia da semana a partir de domingo (0..6) | ||
+ | int tm_yday ; dia do ano (0..365) | ||
+ | int tm_isdst ; é horário de verão nessa data ? (+ : sim, 0 : não, - : informação não disponível). | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | struct tm * gmtime (const time_t *time) | ||
+ | </ | ||
+ | |||
+ | Função similar a '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | time_t mktime (struct tm *brokentime) | ||
+ | </ | ||
+ | |||
+ | Esta função converte uma data no formato '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | char * asctime (const struct tm *brokentime) | ||
+ | char * ctime | ||
+ | </ | ||
+ | |||
+ | Convertem a data descrita em '' | ||
+ | |||
+ | Um pequeno exemplo do uso da função '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | |||
+ | int main (int argc, char * argv[]) | ||
+ | { | ||
+ | | ||
+ | | ||
+ | |||
+ | ct = time (NULL) ; | ||
+ | lt = localtime (&ct) ; | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== O relógio do sistema ===== | ||
+ | |||
+ | |||
+ | Algumas funções permitem a um processo conhecer seu uso de tempo de processador: | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | clock_t clock(void) | ||
+ | </ | ||
+ | |||
+ | Informa o tempo de CPU usado pelo processo, em pulsos de relógio (//clock ticks//). Para conhecer o tempo em segundos, o valor informado deve ser dividido pela constante '' | ||
+ | |||
+ | **Importante**: | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | |||
+ | clock_t start, end; | ||
+ | double cpu_time_used; | ||
+ | |||
+ | start = clock(); | ||
+ | ... /* do the work */ | ||
+ | end = clock(); | ||
+ | cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC; | ||
+ | </ | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | clock_t times (struct tms *buffer) | ||
+ | </ | ||
+ | |||
+ | Esta função retorna informações detalhadas sobre o uso de tempo de processador pelo processo corrente e seus descendentes em '' | ||
+ | |||
+ | A estrutura '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | struct tms | ||
+ | { | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Todos os tempos são informados em pulsos de relógio (//clock ticks//); ao contrário da função '' | ||
+ | |||
+ | ===== Temporizadores ===== | ||
+ | |||
+ | As funções '' | ||
+ | |||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | O programador deve definir um tratador (// | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | int setitimer (int which, struct itimerval *new, struct itimerval *old) | ||
+ | </ | ||
+ | |||
+ | Arma o temporizador indicado por wich de acordo com o prazo definido em '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | int getitimer (int which, struct itimerval *old) | ||
+ | </ | ||
+ | |||
+ | Retorna informação sobre o temporizador indicado em '' | ||
+ | |||
+ | A estrutura itimerval usada pela funções acima tem o seguinte formato (a estrutura '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | struct itimerval | ||
+ | { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | unsigned int alarm (unsigned int seconds) | ||
+ | </ | ||
+ | |||
+ | Esta função é uma forma mais simples (e antiga) de armar o temporizador '' | ||
+ | |||
+ | Um pequeno exemplo do uso de temporizadores: | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | // tratador do sinal SIGALRM (disparo do timer) | ||
+ | void disparo_timer (int signum) | ||
+ | { | ||
+ | | ||
+ | } | ||
+ | |||
+ | int main () | ||
+ | { | ||
+ | | ||
+ | | ||
+ | | ||
+ | // define a ação para o sinal SIGALRM | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | // ajusta valores do temporizador | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | // arma o temporizador | ||
+ | | ||
+ | | ||
+ | // laço vazio | ||
+ | while (1) | ||
+ | sleep (1); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== Sleeping ===== | ||
+ | |||
+ | A função '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | unsigned int sleep (unsigned int seconds) | ||
+ | </ | ||
+ | |||
+ | O processo será " | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | int nanosleep (const struct timespec *requested_time, | ||
+ | </ | ||
+ | |||
+ | Esta função permite definir períodos de espera inferiores a um segundo. A duração da espera é definida pela estrutura '' | ||
+ | |||
+ | As estruturas '' | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | struct timespec | ||
+ | { | ||
+ | long int tv_sec ; número de segundos | ||
+ | long int tv_nsec ; número de nano-segundos. | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== Atividades ===== | ||
+ | |||
+ | * Construa uma função '' | ||
+ | |||
+ | Se passaram 3.029384 segundos desde o início do programa | ||
+ | |||
+ | * Construa um mecanismo baseado em temporizador que informe na tela a seguinte saída, uma vez por minuto: | ||
+ | |||
+ | Hoje é 18/10 e agora são 15:30 | ||
+ | |||
+ | * O utilitário UNIX '' | ||
+ | |||
+ | < | ||
+ | $ time ls -R /usr | ||
+ | ... | ||
+ | 0.580u 1.070s 0:31.66 5.2% 0+0k 0+0io 182pf+0w | ||
+ | </ | ||
+ | |||
+ | Ao terminar o comando, são informados o tempo de execução do processo em modo usuário, em modo núcleo, o tempo total decorrido na execução e algumas outras informações sobre entrada/ | ||