Процессор не выполняет вычисления использования самостоятельно. У него могут быть аппаратные функции, чтобы облегчить эту задачу, но в основном это работа операционной системы. Очевидно, что детали реализации будут различаться (особенно в случае многоядерных систем).
Общая идея состоит в том, чтобы увидеть, сколько времени занимает очередь ЦП. Операционная система может периодически смотреть на планировщик, чтобы определить количество действий, которые она должна выполнить.
Это функция Linux в (извлечено из Википедии), которая выполняет указанные вычисления :
#define FSHIFT 11 /* nr of bits of precision */
#define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */
#define LOAD_FREQ (5*HZ) /* 5 sec intervals */
#define EXP_1 1884 /* 1/exp(5sec/1min) as fixed-point */
#define EXP_5 2014 /* 1/exp(5sec/5min) */
#define EXP_15 2037 /* 1/exp(5sec/15min) */
#define CALC_LOAD(load,exp,n) \
load *= exp; \
load += n*(FIXED_1-exp); \
load >>= FSHIFT;
unsigned long avenrun[3];
static inline void calc_load(unsigned long ticks)
{
unsigned long active_tasks; /* fixed-point */
static int count = LOAD_FREQ;
count -= ticks;
if (count < 0) {
count += LOAD_FREQ;
active_tasks = count_active_tasks();
CALC_LOAD(avenrun[0], EXP_1, active_tasks);
CALC_LOAD(avenrun[1], EXP_5, active_tasks);
CALC_LOAD(avenrun[2], EXP_15, active_tasks);
}
}
Что касается второй части вашего вопроса, большинство современных операционных систем многозадачны . Это означает, что ОС не позволит программам занимать все время обработки и не будет выделять их для себя (если вы этого не сделаете) . Другими словами, даже если приложение кажется зависшим, ОС может все же украсть некоторое время для своей собственной работы.