====== std.systeminfo — Systeminformationen ====== → [[lyx_-_programmiersprache:units|Zurück zur Unit-Übersicht]] Liest Kennzahlen des laufenden Systems aus dem ''/proc''-Dateisystem: Arbeitsspeicher, Systemlast, Laufzeit, Prozessdaten und CPU-Zeiten. Reine Lesezugriffe, keine besonderen Rechte nötig, **nur unter Linux** verwendbar. Einsatzbereiche: Überwachungsagenten, Ressourcenprüfungen vor dem Start eines Dienstes, Diagnoseausgaben. **Autor:** Andreas Röne\\ **Copyright:** 2024–2025 Andreas Röne\\ **Quelle:** ''std/systeminfo.lyx'' **Seit lyxc 1.0.20F liest die Unit tatsächlich ''/proc''** (#1469, #1470, #1471). Gegen das laufende System geprüft: ^ Funktion ^ gemeldet ^ System ^ | ''GetLogicalCores'' | 8 | ''nproc'' = 8 | | ''GetPhysicalCores'' | 4 | ''lscpu'': 4 Kerne je Sockel | | ''GetSMTWidth'' | 2 | 8 / 4 = 2 | | ''GetCpuUserTime'' | 28500711 | ''/proc/stat'': 28500713 | | ''GetCpuIdleTime'' | 127222408 | ''/proc/stat'': 127222410 | | ''GetUptime'' | 310845 | ''/proc/uptime'': 310845 s | Die kleinen Abweichungen bei den CPU-Zeiten sind der Zeitabstand zwischen den beiden Messungen — die Werte laufen weiter. Früher waren die Kernzahlen fest verdrahtet (8, 4, 1), die CPU-Zeiten ohne Bezug zu ''/proc/stat'' und die Uptime in Hundertstelsekunden. ===== Import ===== import std.systeminfo; ---- ===== Funktionen ===== ==== Arbeitsspeicher ==== Alle Werte in **Kilobyte**, direkt aus ''/proc/meminfo''. ^ Signatur ^ Beschreibung ^ Status ^ | ''GetTotalMemory(): int64'' | ''MemTotal'' — gesamter Arbeitsspeicher | ok | | ''GetAvailableMemory(): int64'' | ''MemAvailable'' — ohne Auslagern nutzbar | ok | | ''GetFreeMemory(): int64'' | ''MemFree'' — gar nicht belegt | ok | ''MemAvailable'' ist der Wert, den man für „wie viel Platz habe ich noch" braucht: er zählt Puffer und Cache mit, die das System bei Bedarf freigibt. ''MemFree'' ist auf einem eingelaufenen System immer klein und sagt wenig aus. ==== Systemlast und Laufzeit ==== ^ Signatur ^ Beschreibung ^ Status ^ | ''GetLoadAverage1(): int64'' | Last der letzten Minute, **in Hundertstel** (229 = 2,29) | ok | | ''GetLoadAverage5(): int64'' | Last der letzten 5 Minuten, in Hundertstel | ok | | ''GetLoadAverage15(): int64'' | Last der letzten 15 Minuten, in Hundertstel | ok | | ''GetUptime(): int64'' | Laufzeit seit Systemstart, **in Hundertstelsekunden** | Einheit irreführend (#1471) | | ''GetRunningProcesses(): int64'' | Liefert die **Gesamtzahl** der Prozesse | Name irreführend (#1471) | ==== Eigener Prozess ==== Aus ''/proc/self/stat''. ^ Signatur ^ Beschreibung ^ Status ^ | ''GetProcessId(): int64'' | eigene PID | ok | | ''GetParentProcessId(): int64'' | PID des Elternprozesses | ok | | ''GetUserTime(): int64'' | verbrauchte Benutzerzeit in Uhrticks | ok | | ''GetSystemTime(): int64'' | verbrauchte Systemzeit in Uhrticks | ok | | ''GetNumThreads(): int64'' | Zahl der eigenen Threads | ok | Ein Uhrtick ist auf üblichen Linux-Systemen 1/100 Sekunde; der genaue Wert steht in ''sysconf(_SC_CLK_TCK)'', das [[lyx_-_programmiersprache:units:os|std.os]] bereitstellt. ==== CPU und Betriebssystem ==== ^ Signatur ^ Beschreibung ^ Status ^ | ''GetLogicalCores(): int64'' | Logische Kerne | **behoben** ([[https://github.com/SEOLizer/LyX-Compiler/issues/1469|#1469]]) | | ''GetPhysicalCores(): int64'' | Physische Kerne | **behoben** (#1469) | | ''GetSMTWidth(): int64'' | SMT-Breite | **behoben** (#1469) | | ''GetCpuUserTime(): int64'' | Globale Benutzerzeit in Jiffies | **behoben** ([[https://github.com/SEOLizer/LyX-Compiler/issues/1470|#1470]]) | | ''GetCpuSystemTime(): int64'' | Globale Systemzeit in Jiffies | **behoben** (#1470) | | ''GetCpuIdleTime(): int64'' | Globale Leerlaufzeit in Jiffies | **behoben** (#1470) | | ''GetOS(): int64'' | 0 wenn ''/proc/version'' lesbar ist, sonst −1 | ok, aber wenig aussagekräftig | Die Messwerte zu diesen sechs Funktionen stehen im Kasten am Seitenanfang. Die Zeiten sind **Jiffies**, keine Sekunden — üblicherweise 100 je Sekunde; für Auslastungsangaben zählt ohnehin nur die Differenz zweier Messungen. ''GetOS'' prüft lediglich, ob sich ''/proc/version'' öffnen lässt. Es ist damit ein Test auf „Linux mit gemountetem ''/proc''", keine Betriebssystemkennung. ---- ===== Beispiel ===== import std.systeminfo; fn main(): int64 { // Speicher — die Werte kommen in Kilobyte aus /proc/meminfo var gesamt: int64 := GetTotalMemory(); var frei: int64 := GetAvailableMemory(); PrintLn("Speicher gesamt: ", IntToStr(gesamt / 1024), " MiB"); PrintLn("davon verfuegbar: ", IntToStr(frei / 1024), " MiB"); PrintLn("Auslastung: ", IntToStr((gesamt - frei) * 100 / gesamt), " %"); // Systemlast — Hundertstel, also 229 = 2,29 PrintLn("Last 1/5/15 min: ", IntToStr(GetLoadAverage1()), " / ", IntToStr(GetLoadAverage5()), " / ", IntToStr(GetLoadAverage15()), " (Hundertstel)"); // Uptime — ebenfalls Hundertstelsekunden var upSek: int64 := GetUptime() / 100; PrintLn("Uptime: ", IntToStr(upSek / 3600), " h ", IntToStr((upSek % 3600) / 60), " min"); // Eigener Prozess PrintLn("eigene PID: ", IntToStr(GetProcessId())); PrintLn("Eltern-PID: ", IntToStr(GetParentProcessId())); PrintLn("eigene Threads: ", IntToStr(GetNumThreads())); return 0; } Ausgabe: Speicher gesamt: 31985 MiB davon verfuegbar: 22922 MiB Auslastung: 28 % Last 1/5/15 min: 232 / 292 / 308 (Hundertstel) Uptime: 26 h 17 min eigene PID: 980337 Eltern-PID: 980285 eigene Threads: 1 Gegenprobe mit ''free -m'' und ''/proc/loadavg'' im selben Moment: Speicher: 31985 gesamt ... 22922 verfügbar 2.32 2.92 3.08 7/1343 980345 uptime 26 h 17 min Speicher, Last und Laufzeit stimmen überein. ---- ===== Was nicht stimmt ===== Geprüft mit ''lyxc 1.0.21A''. ==== CPU-Kerne sind fest verdrahtet (#1469) ==== pub fn GetLogicalCores(): int64 { return 8; } Dasselbe bei ''GetPhysicalCores'' (4) und ''GetSMTWidth'' (1). Auf der Entwicklungsmaschine fällt das nicht auf, weil dort tatsächlich 8 logische und 4 physische Kerne vorhanden sind — ''GetSMTWidth'' ist aber selbst hier falsch, ''lscpu'' meldet 2 Threads je Kern. Der übliche Verwendungszweck ist die Größe eines Thread-Pools. Auf einer Zwei-Kern-VM werden damit 8 Arbeiter gestartet, auf einem 64-Kern-Server ebenfalls 8. Bis zum Fix die Kernzahl selbst ermitteln, etwa über die Zahl der ''processor''-Zeilen in ''/proc/cpuinfo'' oder über die CPU-Affinität aus [[lyx_-_programmiersprache:units:sched|std.sched]] — letztere berücksichtigt zusätzlich Beschränkungen in Containern. ==== Globale CPU-Zeiten (behoben, #1470) ==== Seit 1.0.20F stammen die Werte aus ''/proc/stat'' und decken sich mit dem System: GetCpuUserTime = 28500711 /proc/stat: 28500713 GetCpuIdleTime = 127222408 /proc/stat: 127222410 Die kleine Abweichung ist der Zeitabstand zwischen den Messungen. ==== GetRunningProcesses zählt alle Prozesse (#1471) ==== GetRunningProcesses = 1341 /proc/loadavg: 2.29 3.24 3.20 1/1341 978795 Zurück kommt die Zahl **hinter** dem Schrägstrich, also alle Prozesse — die 1 davor wären die tatsächlich laufenden. Als „Gesamtzahl der Prozesse" ist die Funktion brauchbar, unter ihrem Namen nicht. ==== GetUptime gibt Hundertstelsekunden (#1471) ==== GetUptime = 9455718 /proc/uptime: 94557.17 Der Parser überliest den Dezimalpunkt und hängt die Nachkommastellen an. Für Sekunden also durch 100 teilen — so wie im Beispiel oben. Dieselbe Darstellung nutzen die Load-Funktionen, dort allerdings sinnvoll, weil sich ein Lastwert ohne Fließkomma nicht anders ausdrücken lässt. ==== Ein ''read''-Syscall je Zeichen ==== Alle Parser der Unit lesen die ''/proc''-Dateien **byteweise** — für ''/proc/stat'' sind das mehrere hundert Syscalls pro Aufruf. In einer Schleife, die im Sekundentakt Kennzahlen sammelt, ist das spürbar. Werte lieber einmal holen und weiterreichen, statt sie mehrfach abzufragen. ---- ===== Verwandte Units ===== * [[lyx_-_programmiersprache:units:os|std.os]] — Prozess-IDs, Arbeitsverzeichnis, ''sysconf''-Werte * [[lyx_-_programmiersprache:units:sched|std.sched]] — CPU-Affinität, Priorität, aktuelle CPU * [[lyx_-_programmiersprache:units:time|std.time]] — Laufzeitmessung über die monotone Uhr * [[lyx_-_programmiersprache:units:fs|std.fs]] — ''/proc''-Dateien selbst lesen