====== 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