Является ли время, представленное в тактах или секундах в /proc/stat, /proc/uptime и /proc/[pid]/stat точным или приблизительным

#java #linux

#java #linux

Вопрос:

man proc :»/proc/stat: время простоя, проведенное в простой задаче. Это значение должно быть USER_HZ, умноженное на вторую запись в псевдофайле /proc/uptime.»

Но я обнаружил, что между ними было небольшое расхождение. Далее, на мой взгляд, сумма первой строки /proc/stat, тактов процессора, должна быть равна времени безотказной работы, умноженному на USER_HZ, умноженному на количество ядер, и быть равной полям start_time в /proc/self/stat, умноженному на количество ядер при запуске процесса.

Существует простой код:

 import java.io.FileReader;
import java.io.IOException;
import java.io.BufferedReader;

public class TestTick{
    public static void main(String[] args){
        System.out.println(calTotTicks()/12.0/calSelfStartTime());
        System.out.println(12.0*uptime()*100/calTotTicks());
        System.out.println(calIdleTicks()/100/idleTime());
        System.out.println(calSelfStartTime()/100/uptime());
    }

    private static long calTotTicks(){
        try{
            BufferedReader reader = new BufferedReader(new FileReader("/proc/stat"));
            String stat=reader.readLine();
            String[] stats = stat.split("\s ");
            long tot = 0;
            for(int i=1;i<stats.length;  i)
                tot  = Long.parseLong(stats[i]);
            return tot;
        }catch(IOException e){
            System.out.println(e);
            System.exit(1);
        }
        return 0;
    }

    private static long calIdleTicks(){
        try{
            BufferedReader reader = new BufferedReader(new FileReader("/proc/stat"));
            String[] stats = reader.readLine().split("\s ");
            return Long.parseLong(stats[4]);
        }catch(IOException e){
            System.out.println(e);
            System.exit(1);
        }
        return 0;
    }

    private static long calSelfStartTime(){
        try{
            BufferedReader reader = new BufferedReader(new FileReader("/proc/self/stat"));
            String[] stats = reader.readLine().split("\s ");
            return Long.parseLong(stats[21]);
        }catch(IOException e){
            System.out.println(e);
            System.exit(1);
        }
        return 0;
    }

    private static double uptime(){
        try{
            BufferedReader reader = new BufferedReader(new FileReader("/proc/uptime"));
            String stat = reader.readLine();
            String[] stats = stat.split("\s ");
            return Double.parseDouble(stats[0]);
        }catch(IOException e){
            System.out.println(e);
            System.exit(1);
        }
        return 0.0;
    }

    private static double idleTime(){
        try{
            BufferedReader reader = new BufferedReader(new FileReader("/proc/uptime"));
            String[] stats = reader.readLine().split("\s ");
            return Double.parseDouble(stats[1]);
        }catch(IOException e){
            System.out.println(e);
            System.exit(1);
        }
        return 0.0;
    }
}
 

На моем компьютере установлена версия Linux 4.4.0-18362-Microsoft 12 ядер, а USER_HZ равно 100. Результат одного запуска

 1.0018526913814474
0.9981444139842264
1.0077164731297508
0.9999877709392094
 

Результаты нескольких запусков различаются, и все они кажутся близкими к 1, но разница в абсолютных числах огромна. Так что номера тиков в этих файлах не точны, или, может быть, я ошибаюсь.

Спасибо всем за любую помощь!

Комментарии:

1. Имейте в виду, что вы не читаете эти файлы атомарно — вы читаете один за другим, создавая несколько объектов по пути. Каждый из этих вызовов метода, безусловно, требует много циклов процессора, и вы вызываете их несколько раз.

2. Спасибо за ваш ответ, но он не решает всех вопросов. Предположим, что при запуске процесса, calIdleTicks() = 100 * idleTime() , в то время как программа возвращается calIdleTicks() - 100 * idleTime() = 201912 , это означает, что ошибка составляет около 168 секунд, что невозможно. @Халк