8.2 СИСТЕМНЫЕ ОПЕРАЦИИ, СВЯЗАННЫЕ СО ВРЕМЕНЕМ 
 
Существует несколько системных
функций, имеющих отношение к
времени протекания процесса: stime,
time, times и alarm. Первые две имеют дело с
глобальным системным временем,
последние две - с временем
выполнения отдельных процессов.  
Функция stime дает
суперпользователю возможность
заносить в глобальную переменную
значение глобальной переменной.
Выбирается время из этой
переменной с помощью функции time:  
   time(tloc); 
где tloc - указатель на переменную,
принадлежащую процессу, в которую
заносится возвращаемое функцией
значение. Функция возвращает это
значение и из самой себя, например,
команде date, которая вызывает эту
функцию, чтобы определить текущее
время.  
Функция times возвращает суммарное
время выполнения процесса и всех
его потомков, прекративших
существование, в режимах ядра и
задачи. Синтаксис вызова функции:  
   times(tbuffer)
    struct tms *tbuffer;
где tms - имя структуры, в которую
помещаются возвращаемые значения и
которая описывается следующим
образом:  
   struct tms {
       /* time_t - имя структуры данных, в которой хранится время       */
       time_t tms_utime;  /* время выполнения процесса в режиме задачи  */
       time_t tms_stime;  /* время выполнения процесса в режиме ядра    */
       time_t tms_cutime;  /* время выполнения потомков в режиме задачи */
       time_t tms_cstime;  /* время выполнения потомков в режиме ядра   */
    };
Функция times возвращает
время, прошедшее "с некоторого
произвольного момента в
прошлом", как правило, с момента
загрузки системы.   
    
        
     #include <sys/types.h>                                     
     #include <sys/times.h>                                     
     extern long times();                                       
                                                                
     main()                                                     
     {                                                          
        int i;                                                  
        /* tms - имя структуры данных, состоящей из 4 элемен-   
           тов */                                               
        struct tms pb1,pb2;                                     
        long pt1,pt2;                                           
                                                                
        pt1 = times(&pb1);                                      
        for (i = 0; i < 10; i++)                                
             if (fork() == 0)                                   
                 child(i);                                      
                                                                
        for (i = 0; i < 10; i++)                                
             wait((int*) 0);                                    
        pt2 = times(&pb2);                                      
        printf("процесс-родитель: реальное время %u             
                в режиме задачи %u в режиме ядра %u             
                потомки: в режиме задачи %u в режиме ядра %un",
                pt2 - pt1,pb2.tms_utime - pb1.tms_utime,        
                pb2.tms_stime - pb1.tms_stime,                  
                pb2.tms_cutime - pb1.tms_cutime,                
                pb2.tms_cstime - pb1.tms_cstime);               
     }                                                          
                                                                
     child(n);                                                  
        int n;                                                  
     {                                                          
        int i;                                                  
        struct tms cb1,cb2;                                     
        long t1,t2;                                             
                                                                
        t1 = times(&cb1);                                       
        for (i = 0; i < 10000; i++)                             
             ;                                                  
        t2 = times(&cb2);                                       
        printf("потомок %d: реальное время %u в режиме задачи %u
                в режиме ядра %un",n,t2 - t1,                  
                cb2.tms_utime - cb1.tms_utime,                  
                cb2.tms_stime - cb1.tms_stime);                 
        exit();                                                 
     }                                                          
         | 
     
 
 
Рисунок 8.7. Пример
программы, использующей функцию times
 
На Рисунке 8.7 приведена
программа, в которой
процесс-родитель создает 10
потомков, каждый из которых 10000 раз
выполняет пустой цикл.
Процесс-родитель обращается к
функции times перед созданием
потомков и после их завершения, в
свою очередь потомки вызывают эту
функцию перед началом цикла и после
его завершения. Кто-то по наивности
может подумать, что время
выполнения потомков процесса в
режимах задачи и ядра равно сумме
соответствующих слагаемых каждого
потомка, а реальное время
процесса-родителя является суммой
реального времени его потомков.
Однако, время выполнения потомков
не включает в себя время,
затраченное на исполнение
системных функций fork и exit, кроме
того оно может быть искажено за
счет обработки прерываний и
переключений контекста.  
С помощью системной функции alarm
пользовательские процессы могут
инициировать посылку сигналов
тревоги ("будильника") через
кратные промежутки времени.
Например, программа на Рисунке 8.8 каждую
минуту проверяет время доступа к
файлу и, если к файлу было
произведено обращение, выводит
соответствующее сообщение. Для
этого в цикле, с помощью функции stat,
устанавливается момент последнего
обращения к файлу и, если оно имело
место в течение последней минуты,
выводится сообщение. Затем процесс
с помощью функции signal делает
распоряжение принимать сигналы
тревоги, с помощью функции alarm
задает интервал между сигналами в 60
секунд и с помощью функции pause
приостанавливает свое выполнение
до момента получения сигнала. Через
60 секунд сигнал поступает, ядро
подготавливает стек задачи к
вызову функции обработки сигнала
wakeup, функция возвращает управление
на оператор, следующий за вызовом
функции pause, и процесс исполняет
цикл вновь.  
Все перечисленные функции работы
с временем протекания процесса
объединяет то, что они опираются на
показания системных часов
(таймера). Обрабатывая прерывания
по таймеру, ядро обращается к
различным таймерным счетчикам и
инициирует соответствующее
действие.  
Предыдущая
глава || Оглавление
|| Следующая глава 
  
 
 |