modul Verarbeiten
Modul Verarbeiten repräsentiert einen Prozess im zugrundeliegenden Betriebssystem. Seine Methoden unterstützen die Verwaltung des aktuellen Prozesses und seiner Kindprozesse.
Prozess-Erzeugung
Jede der folgenden Methoden führt einen gegebenen Befehl in einem neuen Prozess oder einer neuen Subshell aus, oder mehrere Befehle in neuen Prozessen und/oder Subshells. Die Wahl des Prozesses oder der Subshell hängt von der Form des Befehls ab; siehe Argument command_line oder exe_path.
-
Process.spawn,Kernel#spawn: Führt den Befehl aus; gibt die neue PID zurück, ohne auf die Fertigstellung zu warten. -
Process.exec: Ersetzt den aktuellen Prozess durch Ausführung des Befehls.
Zusätzlich
-
Methode
Kernel#systemführt eine gegebene Befehlszeile (String) in einer Subshell aus; gibttrue,falseodernilzurück. -
Methode
Kernel#`führt eine gegebene Befehlszeile (String) in einer Subshell aus; gibt dessen $stdout-String zurück. -
Modul
Open3unterstützt die Erstellung von Kindprozessen mit Zugriff auf deren $stdin, $stdout und $stderr Streams.
Ausführungsumgebung
Optionales führendes Argument env ist ein Hash von Name/Wert-Paaren, wobei jeder Name ein String und jeder Wert ein String oder nil ist; jedes Name/Wert-Paar wird zu ENV im neuen Prozess hinzugefügt.
Process.spawn( 'ruby -e "p ENV[\"Foo\"]"') Process.spawn({'Foo' => '0'}, 'ruby -e "p ENV[\"Foo\"]"')
Ausgabe
"0"
Die Auswirkung ist normalerweise ähnlich wie das Aufrufen von ENV#update mit dem Argument env, wobei jede benannte Umgebungsvariable erstellt oder aktualisiert (wenn der Wert nicht nil ist) oder gelöscht wird (wenn der Wert nil ist).
Einige Änderungen am aufrufenden Prozess können jedoch bestehen bleiben, wenn der neue Prozess fehlschlägt. Zum Beispiel werden harte Ressourcenlimits nicht wiederhergestellt.
Argument command_line oder exe_path
Das erforderliche String-Argument ist eines der folgenden
-
command_line, wenn es mit einem Shell-reservierten Wort oder einem speziellen Built-in beginnt oder wenn es ein oder mehrere Meta-Zeichen enthält. -
exe_pathandernfalls.
Argument command_line
Das Zeichenkettenargument command_line ist eine Befehlszeile, die an eine Shell übergeben wird; sie muss mit einem reservierten Shell-Wort beginnen, mit einem speziellen Built-in beginnen oder Metazeichen enthalten.
system('if true; then echo "Foo"; fi') # => true # Shell reserved word. system('exit') # => true # Built-in. system('date > /tmp/date.tmp') # => true # Contains meta character. system('date > /nop/date.tmp') # => false system('date > /nop/date.tmp', exception: true) # Raises RuntimeError.
Die Befehlszeile kann auch Argumente und Optionen für den Befehl enthalten.
system('echo "Foo"') # => true
Ausgabe
Foo
Siehe Ausführungs-Shell für Details zur Shell.
Argument exe_path
Das Argument exe_path ist eines der folgenden:
-
Der String-Pfad zu einer ausführbaren Datei, die aufgerufen werden soll
Beispiel
system('/usr/bin/date') # => true # Path to date on Unix-style system. system('foo') # => nil # Command execlution failed.
Ausgabe
Thu Aug 31 10:06:48 AM CDT 2023
Ein Pfad oder Befehlsname, der Leerzeichen ohne Argumente enthält, kann nicht von
command_lineoben unterschieden werden, daher müssen Sie den gesamten Befehlsnamen plattformabhängig mit einer Shell zitieren oder escapen oder die Array-Form unten verwenden.Wenn
exe_pathkeinen Pfadtrenner enthält, wird eine ausführbare Datei aus den Verzeichnissen gesucht, die mit der UmgebungsvariablePATHangegeben sind. Was das Wort "ausführbar" hier bedeutet, hängt von der Plattform ab.Auch wenn die Datei als "ausführbar" gilt, ist ihr Inhalt möglicherweise nicht im richtigen ausführbaren Format. In diesem Fall versucht Ruby, sie mithilfe von
/bin/shunter einem Unix-ähnlichen System auszuführen, ähnlich wie system(3) dies tut.File.write('shell_command', 'echo $SHELL', perm: 0o755) system('./shell_command') # prints "/bin/sh" or something.
-
Ein 2-Element-Array, das den Pfad zu einer ausführbaren Datei und den String enthält, der als Name des ausgeführten Prozesses verwendet werden soll
Beispiel
pid = spawn(['sleep', 'Hello!'], '1') # 2-element array. p `ps -p #{pid} -o command=`
Ausgabe
"Hello! 1\n"
Argumente args
Wenn command_line keine Shell-Meta-Zeichen außer Leerzeichen und Tabs enthält oder exe_path angegeben ist, ruft Ruby die ausführbare Datei direkt auf. Diese Form verwendet keine Shell.
spawn("doesnt_exist") # Raises Errno::ENOENT spawn("doesnt_exist", "\n") # Raises Errno::ENOENT spawn("doesnt_exist\n") # => false # sh: 1: doesnot_exist: not found
Die Fehlermeldung stammt von einer Shell und variiert je nach System.
Wenn nach exe_path ein oder mehrere args angegeben sind, ist jedes davon ein Argument oder eine Option, die an die ausführbare Datei übergeben werden soll.
Beispiel
system('echo', '<', 'C*', '|', '$SHELL', '>') # => true
Ausgabe
< C* | $SHELL >
Es gibt jedoch Ausnahmen unter Windows. Siehe Ausführungs-Shell unter Windows.
Wenn Sie einen Pfad mit Leerzeichen ohne Argumente ohne Shell aufrufen möchten, müssen Sie ein 2-Element-Array exe_path verwenden.
Beispiel
path = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome' spawn(path) # Raises Errno::ENOENT; No such file or directory - /Applications/Google spawn([path] * 2)
Ausführungsoptionen
Optionales nachgestelltes Argument options ist ein Hash von Ausführungsoptionen.
Arbeitsverzeichnis (:chdir)
Standardmäßig ist das Arbeitsverzeichnis für den neuen Prozess dasselbe wie das des aktuellen Prozesses.
Dir.chdir('/var') Process.spawn('ruby -e "puts Dir.pwd"')
Ausgabe
/var
Verwenden Sie die Option :chdir, um das Arbeitsverzeichnis für den neuen Prozess festzulegen.
Process.spawn('ruby -e "puts Dir.pwd"', {chdir: '/tmp'})
Ausgabe
/tmp
Das Arbeitsverzeichnis des aktuellen Prozesses wird nicht geändert.
Dir.pwd # => "/var"
Datei-Umleitung (Dateideskriptor)
Verwenden Sie Ausführungsoptionen für die Datei-Umleitung im neuen Prozess.
Der Schlüssel für eine solche Option kann ein Integer-Dateideskriptor (fd) sein, der eine Quelle angibt, oder ein Array von fds, das mehrere Quellen angibt.
Eine Integer-Quellen-fd kann wie folgt angegeben werden
-
n: Gibt Dateideskriptor n an.
Es gibt diese Kurzsymbole für fds
-
:in: Gibt Dateideskriptor 0 (STDIN) an. -
:out: Gibt Dateideskriptor 1 (STDOUT) an. -
:err: Gibt Dateideskriptor 2 (STDERR) an.
Der mit einer Quelle angegebene Wert ist einer der folgenden
-
n: Leitet zu fd n im Elternprozess um.
-
filepath: Leitet von oder zu der Datei unterfilepathüberopen(filepath, mode, 0644)um, wobeimode'r'für Quelle:inoder'w'für Quelle:outoder:errist. -
[filepath]: Leitet von der Datei unterfilepathüberopen(filepath, 'r', 0644)um. -
[filepath, mode]: Leitet von oder zu der Datei unterfilepathüberopen(filepath, mode, 0644)um. -
[filepath, mode, perm]: Leitet von oder zu der Datei unterfilepathüberopen(filepath, mode, perm)um. -
[:child, fd]: Leitet zum umgeleitetenfdum. -
:close: Schließt den Dateideskriptor im Kindprozess.
Siehe Zugriffsmodi und Datei-Berechtigungen.
Umgebungsvariablen (:unsetenv_others)
Standardmäßig erbt der neue Prozess Umgebungsvariablen vom Elternprozess; verwenden Sie den Ausführungsoptionsschlüssel :unsetenv_others mit dem Wert true, um Umgebungsvariablen im neuen Prozess zu löschen.
Alle durch die Ausführungsoption env spezifizierten Änderungen werden vorgenommen, nachdem der neue Prozess seine Umgebungsvariablen geerbt oder gelöscht hat; siehe Ausführungsumgebung.
Datei-Erstellungszugriff (:umask)
Verwenden Sie die Ausführungsoption :umask, um den Datei-Erstellungszugriff für den neuen Prozess festzulegen; siehe Zugriffsmodi.
command = 'ruby -e "puts sprintf(\"0%o\", File.umask)"' options = {:umask => 0644} Process.spawn(command, options)
Ausgabe
0644
Prozessgruppen (:pgroup und :new_pgroup)
Standardmäßig gehört der neue Prozess zu derselben Prozessgruppe wie der Elternprozess.
Um eine andere Prozessgruppe anzugeben, verwenden Sie die Ausführungsoption :pgroup mit einem der folgenden Werte
-
true: Erstellt eine neue Prozessgruppe für den neuen Prozess. -
pgid: Erstellt den neuen Prozess in der Prozessgruppe mit der ID pgid.
Nur unter Windows, verwenden Sie die Ausführungsoption :new_pgroup mit dem Wert true, um eine neue Prozessgruppe für den neuen Prozess zu erstellen.
Ressourcenlimits
Verwenden Sie Ausführungsoptionen, um Ressourcenlimits festzulegen.
Die Schlüssel für diese Optionen sind Symbole der Form :rlimit_resource_name, wobei resource_name die kleingeschriebene Form eines der String-Ressourcennamen ist, die unter der Methode Process.setrlimit beschrieben werden. Zum Beispiel entspricht der Schlüssel :rlimit_cpu dem Ressourcenlimit 'CPU'.
Der Wert für einen solchen Schlüssel ist einer der folgenden
-
Ein Integer, der sowohl das aktuelle als auch das maximale Limit angibt.
-
Ein 2-Element-Array von Integern, das die aktuellen und maximalen Limits angibt.
Dateideskriptor-Vererbung
Standardmäßig erbt der neue Prozess Dateideskriptoren vom Elternprozess.
Verwenden Sie die Ausführungsoption :close_others => true, um diese Vererbung zu ändern, indem Sie nicht standardmäßige fds (3 und höher), die nicht anderweitig umgeleitet werden, schließen.
Ausführungs-Shell
Unter einem Unix-ähnlichen System ist die aufgerufene Shell /bin/sh; der gesamte String command_line wird als Argument an die Shell-Option -c übergeben.
Die Shell führt die normale Shell-Expansion für die Befehlszeile durch.
Beispiel
system('echo $SHELL: C*') # => true
Ausgabe
/bin/bash: CONTRIBUTING.md COPYING COPYING.ja
Ausführungs-Shell unter Windows
Unter Windows wird die aufgerufene Shell durch die Umgebungsvariable RUBYSHELL bestimmt, falls definiert, oder andernfalls COMSPEC; der gesamte String command_line wird als Argument an die Option -c für RUBYSHELL sowie an /bin/sh und die Option /c für COMSPEC übergeben. Die Shell wird in den folgenden Fällen automatisch aufgerufen
-
Der Befehl ist ein Built-in von
cmd.exe, wie z. B.echo. -
Die ausführbare Datei ist eine Batch-Datei; ihr Name endet auf
.batoder.cmd.
Beachten Sie, dass der Befehl immer noch im command_line-Format aufgerufen wird, auch wenn er im exe_path-Format aufgerufen wird, da cmd.exe kein Skript mit Namen wie /bin/sh akzeptiert, sondern nur mit der Option /c arbeitet.
Die Standard-Shell cmd.exe führt eine Umgebungsvariablen-Erweiterung durch, verfügt aber nicht über die Globbing-Funktionalität.
Beispiel
system("echo %COMSPEC%: C*")' # => true
Ausgabe
C:\WINDOWS\system32\cmd.exe: C*
Was gibt es hier
Aktueller-Prozess-Getter
-
::argv0: Gibt den Prozessnamen als gefrorenen String zurück. -
::egid: Gibt die effektive Gruppen-ID zurück. -
::euid: Gibt die effektive Benutzer-ID zurück. -
::getpgrp: Gibt die Prozessgruppen-ID zurück. -
::getrlimit: Gibt das Ressourcenlimit zurück. -
::gid: Gibt die (reale) Gruppen-ID zurück. -
::pid: Gibt die Prozess-ID zurück. -
::ppid: Gibt die Prozess-ID des Elternprozesses zurück. -
::uid: Gibt die (reale) Benutzer-ID zurück.
Aktueller-Prozess-Setter
-
::egid=: Setzt die effektive Gruppen-ID. -
::euid=: Setzt die effektive Benutzer-ID. -
::gid=: Setzt die (reale) Gruppen-ID. -
::setproctitle: Setzt den Prozess-Titel. -
::setpgrp: Setzt die Prozessgruppen-ID des Prozesses auf Null. -
::setrlimit: Setzt ein Ressourcenlimit. -
::setsid: Etabliert den Prozess als neuen Sitzungs- und Prozessgruppenführer, ohne steuerndes Terminal. -
::uid=: Setzt die Benutzer-ID.
Aktueller-Prozess-Ausführung
-
::abort: Beendet den Prozess sofort. -
::daemon: Löst den Prozess von seinem steuernden Terminal und lässt ihn im Hintergrund als System-Daemon weiterlaufen. -
::exec: Ersetzt den Prozess durch Ausführung eines externen Befehls. -
::exit: Leitet die Prozessbeendigung ein, indem die AusnahmeSystemExitausgelöst wird (die abgefangen werden kann). -
::exit!: Beendet den Prozess sofort. -
::warmup: Benachrichtigt die Ruby-Virtuelle-Maschine, dass die Bootsequenz für die Anwendung abgeschlossen ist und die VM mit der Optimierung der Anwendung beginnen kann.
Kindprozesse
-
::detach: Schützt einen Kindprozess davor, zu einer Zombie-Prozess zu werden. -
::fork: Erstellt einen Kindprozess. -
::kill: Sendet ein gegebenes Signal an Prozesse. -
::spawn: Erstellt einen Kindprozess. -
::wait,::waitpid: Wartet auf die Beendigung eines Kindprozesses; gibt dessen Prozess-ID zurück. -
::wait2,::waitpid2: Wartet auf die Beendigung eines Kindprozesses; gibt dessen Prozess-ID und Status zurück. -
::waitall: Wartet auf die Beendigung aller Kindprozesse; gibt deren Prozess-IDs und Status zurück.
Prozessgruppen
-
::getpgid: Gibt die Prozessgruppen-ID für einen Prozess zurück. -
::getpriority: Gibt die Scheduling-Priorität für einen Prozess, eine Prozessgruppe oder einen Benutzer zurück. -
::getsid: Gibt die Sitzungs-ID für einen Prozess zurück. -
::groups: Gibt ein Array der Gruppen-IDs in der zusätzlichen Gruppen-Zugriffsliste für diesen Prozess zurück. -
::groups=: Setzt die zusätzliche Gruppen-Zugriffsliste auf das gegebene Array von Gruppen-IDs. -
::initgroups: Initialisiert die zusätzliche Gruppen-Zugriffsliste. -
::last_status: Gibt den Status des zuletzt ausgeführten Kindprozesses im aktuellen Thread zurück. -
::maxgroups: Gibt die maximale Anzahl von Gruppen-IDs zurück, die in der zusätzlichen Gruppen-Zugriffsliste erlaubt sind. -
::maxgroups=: Setzt die maximale Anzahl von Gruppen-IDs, die in der zusätzlichen Gruppen-Zugriffsliste erlaubt sind. -
::setpgid: Setzt die Prozessgruppen-ID eines Prozesses. -
::setpriority: Setzt die Scheduling-Priorität für einen Prozess, eine Prozessgruppe oder einen Benutzer.
Timing
-
::clock_getres: Gibt die Auflösung einer Systemuhr zurück. -
::clock_gettime: Gibt die Zeit von einer Systemuhr zurück. -
::times: Gibt einProcess::Tms-Objekt zurück, das Zeiten für den aktuellen Prozess und seine Kindprozesse enthält.
Constants
- CLOCK_BOOTTIME
-
siehe
Process.clock_gettime - CLOCK_BOOTTIME_ALARM
-
siehe
Process.clock_gettime - CLOCK_MONOTONIC
-
siehe
Process.clock_gettime - CLOCK_MONOTONIC_COARSE
-
siehe
Process.clock_gettime - CLOCK_MONOTONIC_FAST
-
siehe
Process.clock_gettime - CLOCK_MONOTONIC_PRECISE
-
siehe
Process.clock_gettime - CLOCK_MONOTONIC_RAW
-
siehe
Process.clock_gettime - CLOCK_MONOTONIC_RAW_APPROX
-
siehe
Process.clock_gettime - CLOCK_PROCESS_CPUTIME_ID
-
siehe
Process.clock_gettime - CLOCK_PROF
-
siehe
Process.clock_gettime - CLOCK_REALTIME
-
siehe
Process.clock_gettime - CLOCK_REALTIME_ALARM
-
siehe
Process.clock_gettime - CLOCK_REALTIME_COARSE
-
siehe
Process.clock_gettime - CLOCK_REALTIME_FAST
-
siehe
Process.clock_gettime - CLOCK_REALTIME_PRECISE
-
siehe
Process.clock_gettime - CLOCK_SECOND
-
siehe
Process.clock_gettime - CLOCK_TAI
-
siehe
Process.clock_gettime - CLOCK_THREAD_CPUTIME_ID
-
siehe
Process.clock_gettime - CLOCK_UPTIME
-
siehe
Process.clock_gettime - CLOCK_UPTIME_FAST
-
siehe
Process.clock_gettime - CLOCK_UPTIME_PRECISE
-
siehe
Process.clock_gettime - CLOCK_UPTIME_RAW
-
siehe
Process.clock_gettime - CLOCK_UPTIME_RAW_APPROX
-
siehe
Process.clock_gettime - CLOCK_VIRTUAL
-
siehe
Process.clock_gettime - PRIO_PGRP
-
siehe
Process.setpriority - PRIO_PROCESS
-
siehe
Process.setpriority - PRIO_USER
-
siehe
Process.setpriority - RLIMIT_AS
-
Maximale Größe des virtuellen Speichers des Prozesses (Adressraum) in Bytes.
siehe das System-Handbuch getrlimit(2) für Details.
- RLIMIT_CORE
-
Maximale Größe der Core-Datei.
siehe das System-Handbuch getrlimit(2) für Details.
- RLIMIT_CPU
-
CPU-Zeitlimit in Sekunden.
siehe das System-Handbuch getrlimit(2) für Details.
- RLIMIT_DATA
-
Maximale Größe des Datensegments des Prozesses.
siehe das System-Handbuch getrlimit(2) für Details.
- RLIMIT_FSIZE
-
Maximale Größe von Dateien, die der Prozess erstellen darf.
siehe das System-Handbuch getrlimit(2) für Details.
- RLIMIT_MEMLOCK
-
Maximale Anzahl von Bytes an Speicher, die in den RAM gesperrt werden dürfen.
siehe das System-Handbuch getrlimit(2) für Details.
- RLIMIT_MSGQUEUE
-
Gibt das Limit für die Anzahl von Bytes an, die für POSIX-Nachrichtenwarteschlangen für die reale Benutzer-ID des aufrufenden Prozesses zugewiesen werden können.
siehe das System-Handbuch getrlimit(2) für Details.
- RLIMIT_NICE
-
Gibt eine Obergrenze an, bis zu der der Nice-Wert des Prozesses erhöht werden kann.
siehe das System-Handbuch getrlimit(2) für Details.
- RLIMIT_NOFILE
-
Gibt einen Wert an, der eins größer ist als die maximale Dateideskriptor-Nummer, die von diesem Prozess geöffnet werden kann.
siehe das System-Handbuch getrlimit(2) für Details.
- RLIMIT_NPROC
-
Die maximale Anzahl von Prozessen, die für die reale Benutzer-ID des aufrufenden Prozesses erstellt werden können.
siehe das System-Handbuch getrlimit(2) für Details.
- RLIMIT_NPTS
-
Die maximale Anzahl von Pseudo-Terminals, die für die reale Benutzer-ID des aufrufenden Prozesses erstellt werden können.
siehe das System-Handbuch getrlimit(2) für Details.
- RLIMIT_RSS
-
Gibt das Limit (in Seiten) des Resident Set des Prozesses an.
siehe das System-Handbuch getrlimit(2) für Details.
- RLIMIT_RTPRIO
-
Gibt eine Obergrenze für die Echtzeitpriorität an, die für diesen Prozess gesetzt werden kann.
siehe das System-Handbuch getrlimit(2) für Details.
- RLIMIT_RTTIME
-
Gibt ein Limit für die CPU-Zeit an, die ein unter einer Echtzeit-Scheduling-Richtlinie geplanter Prozess verbrauchen kann.
siehe das System-Handbuch getrlimit(2) für Details.
- RLIMIT_SBSIZE
-
Maximale Größe des Socket-Puffers.
- RLIMIT_SIGPENDING
-
Gibt ein Limit für die Anzahl der Signale an, die für die reale Benutzer-ID des aufrufenden Prozesses in die Warteschlange gestellt werden können.
siehe das System-Handbuch getrlimit(2) für Details.
- RLIMIT_STACK
-
Maximale Größe des Stacks in Bytes.
siehe das System-Handbuch getrlimit(2) für Details.
- RLIM_INFINITY
-
siehe
Process.setrlimit - RLIM_SAVED_CUR
-
siehe
Process.setrlimit - RLIM_SAVED_MAX
-
siehe
Process.setrlimit - WNOHANG
-
siehe
Process.wait - WUNTRACED
-
siehe
Process.wait
Öffentliche Klassenmethoden
Source
VALUE
rb_proc__fork(VALUE _obj)
{
rb_pid_t pid = proc_fork_pid();
return PIDT2NUM(pid);
}
Eine interne API für fork. Rufen Sie diese Methode nicht direkt auf. Derzeit wird sie über Kernel#fork, Process.fork und IO.popen mit "-" aufgerufen.
Diese Methode ist nicht für alltäglichen Code gedacht, sondern für Bibliotheken zur Anwendungsüberwachung. Sie können benutzerdefinierten Code vor und nach fork-Ereignissen hinzufügen, indem Sie diese Methode überschreiben.
Hinweis: Process.daemon kann mithilfe von fork(2) implementiert werden, ABER durchläuft diese Methode NICHT. Je nach Grund für das Hooking dieser Methode möchten Sie möglicherweise auch die andere hooken. Siehe dieses Problem für eine detailliertere Diskussion.
Source
static VALUE
f_abort(int c, const VALUE *a, VALUE _)
{
rb_f_abort(c, a);
UNREACHABLE_RETURN(Qnil);
}
Beendet die Ausführung sofort, effektiv durch Aufruf von Kernel.exit(false).
Wenn das String-Argument msg gegeben ist, wird es vor der Beendigung nach STDERR geschrieben; andernfalls, wenn eine Ausnahme ausgelöst wurde, werden ihre Nachricht und ihr Backtrace ausgegeben.
Source
static VALUE
proc_argv0(VALUE process)
{
return rb_orig_progname;
}
Gibt den Namen des ausgeführten Skripts zurück. Der Wert wird durch Zuweisung eines neuen Werts zu $0 nicht beeinflusst.
Diese Methode erschien erstmals in Ruby 2.1, um eine globale Variablen-freie Möglichkeit zu bieten, den Skriptnamen zu erhalten.
Source
static VALUE
rb_clock_getres(int argc, VALUE *argv, VALUE _)
{
int ret;
struct timetick tt;
timetick_int_t numerators[2];
timetick_int_t denominators[2];
int num_numerators = 0;
int num_denominators = 0;
#ifdef HAVE_CLOCK_GETRES
clockid_t c;
#endif
VALUE unit = (rb_check_arity(argc, 1, 2) == 2) ? argv[1] : Qnil;
VALUE clk_id = argv[0];
if (SYMBOL_P(clk_id)) {
#ifdef CLOCK_REALTIME
if (clk_id == RUBY_CLOCK_REALTIME) {
c = CLOCK_REALTIME;
goto getres;
}
#endif
#ifdef CLOCK_MONOTONIC
if (clk_id == RUBY_CLOCK_MONOTONIC) {
c = CLOCK_MONOTONIC;
goto getres;
}
#endif
#ifdef CLOCK_PROCESS_CPUTIME_ID
if (clk_id == RUBY_CLOCK_PROCESS_CPUTIME_ID) {
c = CLOCK_PROCESS_CPUTIME_ID;
goto getres;
}
#endif
#ifdef CLOCK_THREAD_CPUTIME_ID
if (clk_id == RUBY_CLOCK_THREAD_CPUTIME_ID) {
c = CLOCK_THREAD_CPUTIME_ID;
goto getres;
}
#endif
#ifdef RUBY_GETTIMEOFDAY_BASED_CLOCK_REALTIME
if (clk_id == RUBY_GETTIMEOFDAY_BASED_CLOCK_REALTIME) {
tt.giga_count = 0;
tt.count = 1000;
denominators[num_denominators++] = 1000000000;
goto success;
}
#endif
#ifdef RUBY_TIME_BASED_CLOCK_REALTIME
if (clk_id == RUBY_TIME_BASED_CLOCK_REALTIME) {
tt.giga_count = 1;
tt.count = 0;
denominators[num_denominators++] = 1000000000;
goto success;
}
#endif
#ifdef RUBY_TIMES_BASED_CLOCK_MONOTONIC
if (clk_id == RUBY_TIMES_BASED_CLOCK_MONOTONIC) {
tt.count = 1;
tt.giga_count = 0;
denominators[num_denominators++] = get_clk_tck();
goto success;
}
#endif
#ifdef RUBY_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID
if (clk_id == RUBY_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID) {
tt.giga_count = 0;
tt.count = 1000;
denominators[num_denominators++] = 1000000000;
goto success;
}
#endif
#ifdef RUBY_TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID
if (clk_id == RUBY_TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID) {
tt.count = 1;
tt.giga_count = 0;
denominators[num_denominators++] = get_clk_tck();
goto success;
}
#endif
#ifdef RUBY_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID
if (clk_id == RUBY_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID) {
tt.count = 1;
tt.giga_count = 0;
denominators[num_denominators++] = CLOCKS_PER_SEC;
goto success;
}
#endif
#ifdef RUBY_MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC
if (clk_id == RUBY_MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC) {
const mach_timebase_info_data_t *info = get_mach_timebase_info();
tt.count = 1;
tt.giga_count = 0;
numerators[num_numerators++] = info->numer;
denominators[num_denominators++] = info->denom;
denominators[num_denominators++] = 1000000000;
goto success;
}
#endif
}
else if (NUMERIC_CLOCKID) {
#if defined(HAVE_CLOCK_GETRES)
struct timespec ts;
c = NUM2CLOCKID(clk_id);
getres:
ret = clock_getres(c, &ts);
if (ret == -1)
clock_failed("getres", errno, clk_id);
tt.count = (int32_t)ts.tv_nsec;
tt.giga_count = ts.tv_sec;
denominators[num_denominators++] = 1000000000;
goto success;
#endif
}
else {
rb_unexpected_type(clk_id, T_SYMBOL);
}
clock_failed("getres", EINVAL, clk_id);
success:
if (unit == ID2SYM(id_hertz)) {
return timetick2dblnum_reciprocal(&tt, numerators, num_numerators, denominators, num_denominators);
}
else {
return make_clock_result(&tt, numerators, num_numerators, denominators, num_denominators, unit);
}
}
Gibt eine Uhrenauflösung zurück, wie sie von der POSIX-Funktion clock_getres() ermittelt wird.
Process.clock_getres(:CLOCK_REALTIME) # => 1.0e-09
Siehe Process.clock_gettime für die Werte von clock_id und unit.
Beispiele
Process.clock_getres(:CLOCK_PROCESS_CPUTIME_ID, :float_microsecond) # => 0.001 Process.clock_getres(:CLOCK_PROCESS_CPUTIME_ID, :float_millisecond) # => 1.0e-06 Process.clock_getres(:CLOCK_PROCESS_CPUTIME_ID, :float_second) # => 1.0e-09 Process.clock_getres(:CLOCK_PROCESS_CPUTIME_ID, :microsecond) # => 0 Process.clock_getres(:CLOCK_PROCESS_CPUTIME_ID, :millisecond) # => 0 Process.clock_getres(:CLOCK_PROCESS_CPUTIME_ID, :nanosecond) # => 1 Process.clock_getres(:CLOCK_PROCESS_CPUTIME_ID, :second) # => 0
Zusätzlich zu den für unit in Process.clock_gettime unterstützten Werten unterstützt diese Methode :hertz, die ganzzahlige Anzahl von Ticks pro Sekunde (was der Kehrwert von :float_second ist).
Process.clock_getres(:TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID, :hertz) # => 100.0 Process.clock_getres(:TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID, :float_second) # => 0.01
Genauigkeit: Beachten Sie, dass die zurückgegebene Auflösung auf einigen Plattformen aufgrund zugrundeliegender Fehler ungenau sein kann. Ungenaue Auflösungen wurden für verschiedene Uhren gemeldet, darunter :CLOCK_MONOTONIC und :CLOCK_MONOTONIC_RAW unter Linux, macOS, BSD oder AIX, bei Verwendung von ARM-Prozessoren oder bei Verwendung von Virtualisierung.
Source
static VALUE
rb_clock_gettime(int argc, VALUE *argv, VALUE _)
{
int ret;
struct timetick tt;
timetick_int_t numerators[2];
timetick_int_t denominators[2];
int num_numerators = 0;
int num_denominators = 0;
VALUE unit = (rb_check_arity(argc, 1, 2) == 2) ? argv[1] : Qnil;
VALUE clk_id = argv[0];
#ifdef HAVE_CLOCK_GETTIME
clockid_t c;
#endif
if (SYMBOL_P(clk_id)) {
#ifdef CLOCK_REALTIME
if (clk_id == RUBY_CLOCK_REALTIME) {
c = CLOCK_REALTIME;
goto gettime;
}
#endif
#ifdef CLOCK_MONOTONIC
if (clk_id == RUBY_CLOCK_MONOTONIC) {
c = CLOCK_MONOTONIC;
goto gettime;
}
#endif
#ifdef CLOCK_PROCESS_CPUTIME_ID
if (clk_id == RUBY_CLOCK_PROCESS_CPUTIME_ID) {
c = CLOCK_PROCESS_CPUTIME_ID;
goto gettime;
}
#endif
#ifdef CLOCK_THREAD_CPUTIME_ID
if (clk_id == RUBY_CLOCK_THREAD_CPUTIME_ID) {
c = CLOCK_THREAD_CPUTIME_ID;
goto gettime;
}
#endif
/*
* Non-clock_gettime clocks are provided by symbol clk_id.
*/
#ifdef HAVE_GETTIMEOFDAY
/*
* GETTIMEOFDAY_BASED_CLOCK_REALTIME is used for
* CLOCK_REALTIME if clock_gettime is not available.
*/
#define RUBY_GETTIMEOFDAY_BASED_CLOCK_REALTIME ID2SYM(id_GETTIMEOFDAY_BASED_CLOCK_REALTIME)
if (clk_id == RUBY_GETTIMEOFDAY_BASED_CLOCK_REALTIME) {
struct timeval tv;
ret = gettimeofday(&tv, 0);
if (ret != 0)
rb_sys_fail("gettimeofday");
tt.giga_count = tv.tv_sec;
tt.count = (int32_t)tv.tv_usec * 1000;
denominators[num_denominators++] = 1000000000;
goto success;
}
#endif
#define RUBY_TIME_BASED_CLOCK_REALTIME ID2SYM(id_TIME_BASED_CLOCK_REALTIME)
if (clk_id == RUBY_TIME_BASED_CLOCK_REALTIME) {
time_t t;
t = time(NULL);
if (t == (time_t)-1)
rb_sys_fail("time");
tt.giga_count = t;
tt.count = 0;
denominators[num_denominators++] = 1000000000;
goto success;
}
#ifdef HAVE_TIMES
#define RUBY_TIMES_BASED_CLOCK_MONOTONIC \
ID2SYM(id_TIMES_BASED_CLOCK_MONOTONIC)
if (clk_id == RUBY_TIMES_BASED_CLOCK_MONOTONIC) {
struct tms buf;
clock_t c;
unsigned_clock_t uc;
c = times(&buf);
if (c == (clock_t)-1)
rb_sys_fail("times");
uc = (unsigned_clock_t)c;
tt.count = (int32_t)(uc % 1000000000);
tt.giga_count = (uc / 1000000000);
denominators[num_denominators++] = get_clk_tck();
goto success;
}
#endif
#ifdef RUSAGE_SELF
#define RUBY_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID \
ID2SYM(id_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID)
if (clk_id == RUBY_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID) {
struct rusage usage;
int32_t usec;
ret = getrusage(RUSAGE_SELF, &usage);
if (ret != 0)
rb_sys_fail("getrusage");
tt.giga_count = usage.ru_utime.tv_sec + usage.ru_stime.tv_sec;
usec = (int32_t)(usage.ru_utime.tv_usec + usage.ru_stime.tv_usec);
if (1000000 <= usec) {
tt.giga_count++;
usec -= 1000000;
}
tt.count = usec * 1000;
denominators[num_denominators++] = 1000000000;
goto success;
}
#endif
#ifdef HAVE_TIMES
#define RUBY_TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID \
ID2SYM(id_TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID)
if (clk_id == RUBY_TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID) {
struct tms buf;
unsigned_clock_t utime, stime;
if (times(&buf) == (clock_t)-1)
rb_sys_fail("times");
utime = (unsigned_clock_t)buf.tms_utime;
stime = (unsigned_clock_t)buf.tms_stime;
tt.count = (int32_t)((utime % 1000000000) + (stime % 1000000000));
tt.giga_count = (utime / 1000000000) + (stime / 1000000000);
if (1000000000 <= tt.count) {
tt.count -= 1000000000;
tt.giga_count++;
}
denominators[num_denominators++] = get_clk_tck();
goto success;
}
#endif
#define RUBY_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID \
ID2SYM(id_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID)
if (clk_id == RUBY_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID) {
clock_t c;
unsigned_clock_t uc;
errno = 0;
c = clock();
if (c == (clock_t)-1)
rb_sys_fail("clock");
uc = (unsigned_clock_t)c;
tt.count = (int32_t)(uc % 1000000000);
tt.giga_count = uc / 1000000000;
denominators[num_denominators++] = CLOCKS_PER_SEC;
goto success;
}
#ifdef __APPLE__
if (clk_id == RUBY_MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC) {
const mach_timebase_info_data_t *info = get_mach_timebase_info();
uint64_t t = mach_absolute_time();
tt.count = (int32_t)(t % 1000000000);
tt.giga_count = t / 1000000000;
numerators[num_numerators++] = info->numer;
denominators[num_denominators++] = info->denom;
denominators[num_denominators++] = 1000000000;
goto success;
}
#endif
}
else if (NUMERIC_CLOCKID) {
#if defined(HAVE_CLOCK_GETTIME)
struct timespec ts;
c = NUM2CLOCKID(clk_id);
gettime:
ret = clock_gettime(c, &ts);
if (ret == -1)
clock_failed("gettime", errno, clk_id);
tt.count = (int32_t)ts.tv_nsec;
tt.giga_count = ts.tv_sec;
denominators[num_denominators++] = 1000000000;
goto success;
#endif
}
else {
rb_unexpected_type(clk_id, T_SYMBOL);
}
clock_failed("gettime", EINVAL, clk_id);
success:
return make_clock_result(&tt, numerators, num_numerators, denominators, num_denominators, unit);
}
Gibt eine Uhrzeit zurück, wie sie von der POSIX-Funktion clock_gettime() ermittelt wird.
Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID) # => 198.650379677
Argument clock_id sollte ein Symbol oder eine Konstante sein, die die Uhr angibt, deren Zeit zurückgegeben werden soll; siehe unten.
Das optionale Argument unit sollte ein Symbol sein, das die Einheit angibt, die für die zurückgegebene Uhrzeit verwendet werden soll; siehe unten.
Argument clock_id
Argument clock_id gibt die Uhr an, deren Zeit zurückgegeben werden soll; es kann eine Konstante wie Process::CLOCK_REALTIME oder eine Symbolkürzel wie :CLOCK_REALTIME sein.
Die unterstützten Uhren hängen vom zugrundeliegenden Betriebssystem ab; diese Methode unterstützt die folgenden Uhren auf den angegebenen Plattformen (löst Errno::EINVAL aus, wenn sie mit einer nicht unterstützten Uhr aufgerufen wird).
-
:CLOCK_BOOTTIME: Linux 2.6.39. -
:CLOCK_BOOTTIME_ALARM: Linux 3.0. -
:CLOCK_MONOTONIC: SUSv3 bis 4, Linux 2.5.63, FreeBSD 3.0, NetBSD 2.0, OpenBSD 3.4, macOS 10.12, Windows-2000. -
:CLOCK_MONOTONIC_COARSE: Linux 2.6.32. -
:CLOCK_MONOTONIC_FAST: FreeBSD 8.1. -
:CLOCK_MONOTONIC_PRECISE: FreeBSD 8.1. -
:CLOCK_MONOTONIC_RAW: Linux 2.6.28, macOS 10.12. -
:CLOCK_MONOTONIC_RAW_APPROX: macOS 10.12. -
:CLOCK_PROCESS_CPUTIME_ID: SUSv3 bis 4, Linux 2.5.63, FreeBSD 9.3, OpenBSD 5.4, macOS 10.12. -
:CLOCK_PROF: FreeBSD 3.0, OpenBSD 2.1. -
:CLOCK_REALTIME: SUSv2 bis 4, Linux 2.5.63, FreeBSD 3.0, NetBSD 2.0, OpenBSD 2.1, macOS 10.12, Windows-8/Server-2012.Time.nowwird gegenüber:CLOCK_REALTIMEempfohlen. -
:CLOCK_REALTIME_ALARM: Linux 3.0. -
:CLOCK_REALTIME_COARSE: Linux 2.6.32. -
:CLOCK_REALTIME_FAST: FreeBSD 8.1. -
:CLOCK_REALTIME_PRECISE: FreeBSD 8.1. -
:CLOCK_SECOND: FreeBSD 8.1. -
:CLOCK_TAI: Linux 3.10. -
:CLOCK_THREAD_CPUTIME_ID: SUSv3 bis 4, Linux 2.5.63, FreeBSD 7.1, OpenBSD 5.4, macOS 10.12. -
:CLOCK_UPTIME: FreeBSD 7.0, OpenBSD 5.5. -
:CLOCK_UPTIME_FAST: FreeBSD 8.1. -
:CLOCK_UPTIME_PRECISE: FreeBSD 8.1. -
:CLOCK_UPTIME_RAW: macOS 10.12. -
:CLOCK_UPTIME_RAW_APPROX: macOS 10.12. -
:CLOCK_VIRTUAL: FreeBSD 3.0, OpenBSD 2.1.
Beachten Sie, dass SUS für Single Unix Specification steht. SUS enthält POSIX und clock_gettime ist im POSIX-Teil definiert. SUS definiert :CLOCK_REALTIME als obligatorisch, aber :CLOCK_MONOTONIC, :CLOCK_PROCESS_CPUTIME_ID und :CLOCK_THREAD_CPUTIME_ID sind optional.
Bestimmte Emulationen werden verwendet, wenn die gegebene clock_id nicht direkt unterstützt wird.
-
Emulationen für
:CLOCK_REALTIME-
:GETTIMEOFDAY_BASED_CLOCK_REALTIME: Verwendet gettimeofday() definiert durch SUS (in SUSv4 veraltet). Die Auflösung beträgt 1 Mikrosekunde. -
:TIME_BASED_CLOCK_REALTIME: Verwendet time() definiert durch ISO C. Die Auflösung beträgt 1 Sekunde.
-
-
Emulationen für
:CLOCK_MONOTONIC-
:MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC: Verwendet mach_absolute_time(), verfügbar auf Darwin. Die Auflösung ist CPU-abhängig. -
:TIMES_BASED_CLOCK_MONOTONIC: Verwendet den Rückgabewert von times() definiert durch POSIX, alsoBei erfolgreicher Beendigung gibt times() die verstrichene Echtzeit in Ticks zurück, seit einem beliebigen Punkt in der Vergangenheit (z. B. Systemstartzeit).
Zum Beispiel gibt GNU/Linux einen Wert basierend auf Jiffies zurück und dieser ist monoton. 4.4BSD verwendet jedoch gettimeofday() und diese ist nicht monoton. (FreeBSD verwendet stattdessen
:CLOCK_MONOTONIC.)Die Auflösung ist der Tick. Der Befehl "getconf CLK_TCK" zeigt die Ticks pro Sekunde an. (Die Ticks pro Sekunde sind in älteren Systemen durch das HZ-Makro definiert.) Wenn es 100 ist und clock_t ein 32-Bit-Ganzzahltyp ist, beträgt die Auflösung 10 Millisekunden und kann nicht über 497 Tage darstellen.
-
-
Emulationen für
:CLOCK_PROCESS_CPUTIME_ID-
:GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID: Verwendet getrusage() definiert durch SUS. getrusage() wird mit RUSAGE_SELF verwendet, um nur die Zeit für den aufrufenden Prozess zu erhalten (ohne die Zeit für Kindprozesse). Das Ergebnis ist die Addition von Benutzerzeit (ru_utime) und Systemzeit (ru_stime). Die Auflösung beträgt 1 Mikrosekunde. -
:TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID: Verwendet times() definiert durch POSIX. Das Ergebnis ist die Addition von Benutzerzeit (tms_utime) und Systemzeit (tms_stime). tms_cutime und tms_cstime werden ignoriert, um die Zeit für Kindprozesse auszuschließen. Die Auflösung ist der Tick. Der Befehl "getconf CLK_TCK" zeigt die Ticks pro Sekunde an. (Die Ticks pro Sekunde sind in älteren Systemen durch das HZ-Makro definiert.) Wenn es 100 ist, beträgt die Auflösung 10 Millisekunden. -
:CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID: Verwendet clock() definiert durch ISO C. Die Auflösung beträgt1/CLOCKS_PER_SEC.CLOCKS_PER_SECist das C-Level-Makro, das von time.h definiert wird. SUS definiertCLOCKS_PER_SECals 1000000; andere Systeme können es unterschiedlich definieren. WennCLOCKS_PER_SEC1000000 ist (wie in SUS), beträgt die Auflösung 1 Mikrosekunde. WennCLOCKS_PER_SEC1000000 ist und clock_t ein 32-Bit-Ganzzahltyp ist, kann er nicht mehr als 72 Minuten darstellen.
-
Argument unit
Optionales Argument unit (Standard :float_second) gibt die Einheit für den zurückgegebenen Wert an.
-
:float_microsecond: Anzahl der Mikrosekunden als Float. -
:float_millisecond: Anzahl der Millisekunden als Float. -
:float_second: Anzahl der Sekunden als Float. -
:microsecond: Anzahl der Mikrosekunden als Integer. -
:millisecond: Anzahl der Millisekunden als Integer. -
:nanosecond: Anzahl der Nanosekunden als Integer. -
:second: Anzahl der Sekunden als Integer.
Beispiele
Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID, :float_microsecond) # => 203605054.825 Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID, :float_millisecond) # => 203643.696848 Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID, :float_second) # => 203.762181929 Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID, :microsecond) # => 204123212 Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID, :millisecond) # => 204298 Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID, :nanosecond) # => 204602286036 Process.clock_gettime(:CLOCK_PROCESS_CPUTIME_ID, :second) # => 204
Die zugrundeliegende Funktion, clock_gettime(), gibt eine Anzahl von Nanosekunden zurück. Ein Float-Objekt (IEEE 754 double) reicht nicht aus, um den Rückgabewert für :CLOCK_REALTIME darzustellen. Wenn der exakte Nanosekundenwert benötigt wird, verwenden Sie :nanosecond als unit.
Der Ursprung (Zeit Null) des zurückgegebenen Werts ist systemabhängig und kann beispielsweise die Systemstartzeit, die Prozessstartzeit, die Epoche usw. sein.
Der Ursprung in :CLOCK_REALTIME ist definiert als die Epoche: 1970-01-01 00:00:00 UTC; einige Systeme zählen Schaltsekunden und andere nicht, sodass das Ergebnis zwischen den Systemen variieren kann.
Source
static VALUE
proc_daemon(int argc, VALUE *argv, VALUE _)
{
int n, nochdir = FALSE, noclose = FALSE;
switch (rb_check_arity(argc, 0, 2)) {
case 2: noclose = TO_BOOL(argv[1], "noclose");
case 1: nochdir = TO_BOOL(argv[0], "nochdir");
}
prefork();
n = rb_daemon(nochdir, noclose);
if (n < 0) rb_sys_fail("daemon");
return INT2FIX(n);
}
Löst den aktuellen Prozess von seinem steuernden Terminal und lässt ihn im Hintergrund als System-Daemon laufen; gibt null zurück.
Standardmäßig
-
Ändert das aktuelle Arbeitsverzeichnis in das Stammverzeichnis.
-
Leitet $stdin, $stdout und $stderr zum Nullgerät um.
Wenn das optionale Argument nochdir true ist, wird das aktuelle Arbeitsverzeichnis nicht geändert.
Wenn das optionale Argument noclose true ist, werden $stdin, $stdout oder $stderr nicht umgeleitet.
Source
static VALUE
proc_detach(VALUE obj, VALUE pid)
{
return rb_detach_process(NUM2PIDT(pid));
}
Vermeidet die Möglichkeit, dass ein Kindprozess zu einem Zombie-Prozess wird. Process.detach verhindert dies, indem ein separater Ruby-Thread eingerichtet wird, dessen einzige Aufgabe es ist, den Status des Prozesses pid zu ernten, wenn dieser beendet wird.
Diese Methode ist nur dann erforderlich, wenn der Elternprozess niemals auf den Kindprozess wartet.
Dieses Beispiel erntet den zweiten Kindprozess nicht; dieser Prozess erscheint als Zombie in der Prozessstatusanzeige (ps).
pid = Process.spawn('ruby', '-e', 'exit 13') # => 312691 sleep(1) # Find zombies. system("ps -ho pid,state -p #{pid}")
Ausgabe
312716 Z
Dieses Beispiel erntet ebenfalls nicht den zweiten Kindprozess, entkoppelt den Prozess aber, damit er nicht zu einem Zombie wird.
pid = Process.spawn('ruby', '-e', 'exit 13') # => 313213 thread = Process.detach(pid) sleep(1) # => #<Process::Waiter:0x00007f038f48b838 run> system("ps -ho pid,state -p #{pid}") # Finds no zombies.
Der wartende Thread kann die PID des abgetrennten Kindprozesses zurückgeben.
thread.join.pid # => 313262
Source
static VALUE
proc_getegid(VALUE obj)
{
rb_gid_t egid = getegid();
return GIDT2NUM(egid);
}
Gibt die effektive Gruppen-ID für den aktuellen Prozess zurück.
Process.egid # => 500
Nicht auf allen Plattformen verfügbar.
Source
static VALUE
proc_setegid(VALUE obj, VALUE egid)
{
#if defined(HAVE_SETRESGID) || defined(HAVE_SETREGID) || defined(HAVE_SETEGID) || defined(HAVE_SETGID)
rb_gid_t gid;
#endif
check_gid_switch();
#if defined(HAVE_SETRESGID) || defined(HAVE_SETREGID) || defined(HAVE_SETEGID) || defined(HAVE_SETGID)
gid = OBJ2GID(egid);
#endif
#if defined(HAVE_SETRESGID)
if (setresgid(-1, gid, -1) < 0) rb_sys_fail(0);
#elif defined HAVE_SETREGID
if (setregid(-1, gid) < 0) rb_sys_fail(0);
#elif defined HAVE_SETEGID
if (setegid(gid) < 0) rb_sys_fail(0);
#elif defined HAVE_SETGID
if (gid == getgid()) {
if (setgid(gid) < 0) rb_sys_fail(0);
}
else {
rb_notimplement();
}
#else
rb_notimplement();
#endif
return egid;
}
Setzt die effektive Gruppen-ID für den aktuellen Prozess.
Nicht auf allen Plattformen verfügbar.
Source
static VALUE
proc_geteuid(VALUE obj)
{
rb_uid_t euid = geteuid();
return UIDT2NUM(euid);
}
Gibt die effektive Benutzer-ID für den aktuellen Prozess zurück.
Process.euid # => 501
Source
static VALUE
proc_seteuid_m(VALUE mod, VALUE euid)
{
check_uid_switch();
proc_seteuid(OBJ2UID(euid));
return euid;
}
Setzt die effektive Benutzer-ID für den aktuellen Prozess.
Nicht auf allen Plattformen verfügbar.
Source
static VALUE
f_exec(int c, const VALUE *a, VALUE _)
{
rb_f_exec(c, a);
UNREACHABLE_RETURN(Qnil);
}
Ersetzt den aktuellen Prozess, indem eines der folgenden Dinge getan wird
-
Übergabe des Strings
command_linean die Shell. -
Aufrufen der ausführbaren Datei unter
exe_path.
Diese Methode hat potenzielle Sicherheitslücken, wenn sie mit nicht vertrauenswürdigen Eingaben aufgerufen wird. Siehe Command Injection.
Der neue Prozess wird mithilfe des exec-Systemaufrufs erstellt; er kann einige seiner Umgebung vom aufrufenden Programm erben (möglicherweise einschließlich offener Dateideskriptoren).
Das Argument env, falls gegeben, ist ein Hash, der sich auf ENV für den neuen Prozess auswirkt; siehe Ausführungsumgebung.
Das Argument options ist ein Hash von Optionen für den neuen Prozess; siehe Ausführungsoptionen.
Das erste erforderliche Argument ist eines der folgenden
-
command_line, wenn es ein String ist und wenn es mit einem Shell-reservierten Wort oder einem speziellen Built-in beginnt oder wenn es ein oder mehrere Meta-Zeichen enthält. -
exe_pathandernfalls.
Argument command_line
Das Zeichenkettenargument command_line ist eine Befehlszeile, die an eine Shell übergeben wird; sie muss mit einem reservierten Shell-Wort beginnen, mit einem speziellen Built-in beginnen oder Metazeichen enthalten.
exec('if true; then echo "Foo"; fi') # Shell reserved word. exec('exit') # Built-in. exec('date > date.tmp') # Contains meta character.
Die Befehlszeile kann auch Argumente und Optionen für den Befehl enthalten.
exec('echo "Foo"')
Ausgabe
Foo
Siehe Ausführungs-Shell für Details zur Shell.
Löst eine Ausnahme aus, wenn der neue Prozess nicht ausgeführt werden konnte.
Argument exe_path
Das Argument exe_path ist eines der folgenden:
-
Der Zeichenkettenpfad zu einer ausführbaren Datei, die aufgerufen werden soll.
-
Ein Array mit zwei Elementen, das den Pfad zu einer ausführbaren Datei und die Zeichenkette enthält, die als Name des ausgeführten Prozesses verwendet werden soll.
Beispiel
exec('/usr/bin/date')
Ausgabe
Sat Aug 26 09:38:00 AM CDT 2023
Ruby ruft die ausführbare Datei direkt auf. Diese Form verwendet keine Shell; siehe Argumente args für Einschränkungen.
exec('doesnt_exist') # Raises Errno::ENOENT
Wenn ein oder mehrere args angegeben sind, ist jedes ein Argument oder eine Option, die an die ausführbare Datei übergeben werden soll.
exec('echo', 'C*') exec('echo', 'hello', 'world')
Ausgabe
C* hello world
Löst eine Ausnahme aus, wenn der neue Prozess nicht ausgeführt werden konnte.
Source
static VALUE
f_exit(int c, const VALUE *a, VALUE _)
{
rb_f_exit(c, a);
UNREACHABLE_RETURN(Qnil);
}
Leitet die Beendigung des Ruby-Skripts ein, indem SystemExit ausgelöst wird; die Ausnahme kann abgefangen werden. Gibt den Exit-Status status an das zugrundeliegende Betriebssystem zurück.
Die Werte true und false für das Argument status zeigen jeweils Erfolg und Misserfolg an; Die Bedeutung von Integer-Werten ist systemabhängig.
Beispiel
begin exit puts 'Never get here.' rescue SystemExit puts 'Rescued a SystemExit exception.' end puts 'After begin block.'
Ausgabe
Rescued a SystemExit exception. After begin block.
Kurz vor der endgültigen Beendigung führt Ruby alle Exit-Prozeduren aus (siehe Kernel::at_exit) und alle Objektfinalizer (siehe ObjectSpace::define_finalizer).
Beispiel
at_exit { puts 'In at_exit function.' } ObjectSpace.define_finalizer('string', proc { puts 'In finalizer.' }) exit
Ausgabe
In at_exit function. In finalizer.
Source
static VALUE
rb_f_exit_bang(int argc, VALUE *argv, VALUE obj)
{
int istatus;
if (rb_check_arity(argc, 0, 1) == 1) {
istatus = exit_status_code(argv[0]);
}
else {
istatus = EXIT_FAILURE;
}
_exit(istatus);
UNREACHABLE_RETURN(Qnil);
}
Beendet den Prozess sofort; es werden keine Exit-Handler aufgerufen. Gibt den Exit-Status status an das zugrunde liegende Betriebssystem zurück.
Process.exit!(true)
Die Werte true und false für das Argument status zeigen jeweils Erfolg und Misserfolg an; Die Bedeutung von Integer-Werten ist systemabhängig.
Source
static VALUE
rb_f_fork(VALUE obj)
{
rb_pid_t pid;
pid = rb_call_proc__fork();
if (pid == 0) {
if (rb_block_given_p()) {
int status;
rb_protect(rb_yield, Qundef, &status);
ruby_stop(status);
}
return Qnil;
}
return PIDT2NUM(pid);
}
Erzeugt einen Kindprozess.
Mit einem Block wird der Block im Kindprozess ausgeführt; nach Beendigung des Blocks wird der Kindprozess mit dem Status null beendet.
puts "Before the fork: #{Process.pid}" fork do puts "In the child process: #{Process.pid}" end # => 382141 puts "After the fork: #{Process.pid}"
Ausgabe
Before the fork: 420496 After the fork: 420496 In the child process: 420520
Ohne Block wird der fork-Aufruf zweimal zurückgegeben.
-
Einmal im Elternprozess, zurückgegeben wird die PID des Kindprozesses.
-
Einmal im Kindprozess, zurückgegeben wird
nil.
Beispiel
puts "This is the first line before the fork (pid #{Process.pid})" puts fork puts "This is the second line after the fork (pid #{Process.pid})"
Ausgabe
This is the first line before the fork (pid 420199) 420223 This is the second line after the fork (pid 420199) This is the second line after the fork (pid 420223)
In beiden Fällen kann der Kindprozess mit Kernel.exit! beendet werden, um den Aufruf von Kernel#at_exit zu vermeiden.
Um Zombie-Prozesse zu vermeiden, sollte der Elternprozess entweder aufrufen
-
Process.wait, um die Beendigungsstatus seiner Kinder zu sammeln. -
Process.detach, um Desinteresse an ihrem Status zu registrieren.
Der Thread, der fork aufruft, ist der einzige Thread im erzeugten Kindprozess; fork kopiert keine anderen Threads.
Beachten Sie, dass die Methode fork auf einigen Plattformen verfügbar ist, auf anderen jedoch nicht.
Process.respond_to?(:fork) # => true # Would be false on some.
Wenn nicht, können Sie stattdessen ::spawn anstelle von fork verwenden.
Source
static VALUE
proc_getpgid(VALUE obj, VALUE pid)
{
rb_pid_t i;
i = getpgid(NUM2PIDT(pid));
if (i < 0) rb_sys_fail(0);
return PIDT2NUM(i);
}
Returns the process group ID for the given process ID +pid+: Process.getpgid(Process.ppid) # => 25527
Nicht auf allen Plattformen verfügbar.
Source
static VALUE
proc_getpgrp(VALUE _)
{
rb_pid_t pgrp;
#if defined(HAVE_GETPGRP) && defined(GETPGRP_VOID)
pgrp = getpgrp();
if (pgrp < 0) rb_sys_fail(0);
return PIDT2NUM(pgrp);
#else /* defined(HAVE_GETPGID) */
pgrp = getpgid(0);
if (pgrp < 0) rb_sys_fail(0);
return PIDT2NUM(pgrp);
#endif
}
Gibt die Prozessgruppen-ID für den aktuellen Prozess zurück.
Process.getpgid(0) # => 25527 Process.getpgrp # => 25527
Source
static VALUE
proc_getpriority(VALUE obj, VALUE which, VALUE who)
{
int prio, iwhich, iwho;
iwhich = NUM2INT(which);
iwho = NUM2INT(who);
errno = 0;
prio = getpriority(iwhich, iwho);
if (errno) rb_sys_fail(0);
return INT2FIX(prio);
}
Gibt die Scheduling-Priorität für den angegebenen Prozess, die Prozessgruppe oder den Benutzer zurück.
Das Argument kind ist eines von
-
Process::PRIO_PROCESS: Gibt die Priorität für den Prozess zurück. -
Process::PRIO_PGRP: Gibt die Priorität für die Prozessgruppe zurück. -
Process::PRIO_USER: Gibt die Priorität für den Benutzer zurück.
Das Argument id ist die ID für den Prozess, die Prozessgruppe oder den Benutzer; null gibt die aktuelle ID für kind an.
Beispiele
Process.getpriority(Process::PRIO_USER, 0) # => 19 Process.getpriority(Process::PRIO_PROCESS, 0) # => 19
Nicht auf allen Plattformen verfügbar.
Source
static VALUE
proc_getrlimit(VALUE obj, VALUE resource)
{
struct rlimit rlim;
if (getrlimit(rlimit_resource_type(resource), &rlim) < 0) {
rb_sys_fail("getrlimit");
}
return rb_assoc_new(RLIM2NUM(rlim.rlim_cur), RLIM2NUM(rlim.rlim_max));
}
Gibt ein 2-elementiges Array des aktuellen (soft) Limits und des maximalen (hard) Limits für die gegebene resource zurück.
Das Argument resource gibt die Ressource an, deren Limits zurückgegeben werden sollen; siehe Process.setrlimit.
Jeder der zurückgegebenen Werte cur_limit und max_limit ist eine Ganzzahl; siehe Process.setrlimit.
Beispiel
Process.getrlimit(:CORE) # => [0, 18446744073709551615]
Siehe Process.setrlimit.
Nicht auf allen Plattformen verfügbar.
Source
static VALUE
proc_getsid(int argc, VALUE *argv, VALUE _)
{
rb_pid_t sid;
rb_pid_t pid = 0;
if (rb_check_arity(argc, 0, 1) == 1 && !NIL_P(argv[0]))
pid = NUM2PIDT(argv[0]);
sid = getsid(pid);
if (sid < 0) rb_sys_fail(0);
return PIDT2NUM(sid);
}
Gibt die Sitzungs-ID des gegebenen Prozess-IDs pid zurück, oder die des aktuellen Prozesses, wenn keine angegeben ist.
Process.getsid # => 27422 Process.getsid(0) # => 27422 Process.getsid(Process.pid()) # => 27422
Nicht auf allen Plattformen verfügbar.
Source
static VALUE
proc_getgid(VALUE obj)
{
rb_gid_t gid = getgid();
return GIDT2NUM(gid);
}
Gibt die (reale) Gruppen-ID für den aktuellen Prozess zurück.
Process.gid # => 1000
Source
static VALUE
proc_setgid(VALUE obj, VALUE id)
{
rb_gid_t gid;
check_gid_switch();
gid = OBJ2GID(id);
#if defined(HAVE_SETRESGID)
if (setresgid(gid, -1, -1) < 0) rb_sys_fail(0);
#elif defined HAVE_SETREGID
if (setregid(gid, -1) < 0) rb_sys_fail(0);
#elif defined HAVE_SETRGID
if (setrgid(gid) < 0) rb_sys_fail(0);
#elif defined HAVE_SETGID
{
if (getegid() == gid) {
if (setgid(gid) < 0) rb_sys_fail(0);
}
else {
rb_notimplement();
}
}
#endif
return GIDT2NUM(gid);
}
Setzt die Gruppen-ID für den aktuellen Prozess auf new_gid.
Process.gid = 1000 # => 1000
Source
static VALUE
proc_getgroups(VALUE obj)
{
VALUE ary, tmp;
int i, ngroups;
rb_gid_t *groups;
ngroups = getgroups(0, NULL);
if (ngroups == -1)
rb_sys_fail(0);
groups = ALLOCV_N(rb_gid_t, tmp, ngroups);
ngroups = getgroups(ngroups, groups);
if (ngroups == -1)
rb_sys_fail(0);
ary = rb_ary_new();
for (i = 0; i < ngroups; i++)
rb_ary_push(ary, GIDT2NUM(groups[i]));
ALLOCV_END(tmp);
return ary;
}
Gibt ein Array der Gruppen-IDs in der ergänzenden Gruppen-Zugriffsliste für den aktuellen Prozess zurück.
Process.groups # => [4, 24, 27, 30, 46, 122, 135, 136, 1000]
Diese Eigenschaften des zurückgegebenen Arrays sind systemabhängig.
-
Ob (und wie) das Array sortiert ist.
-
Ob das Array effektive Gruppen-IDs enthält.
-
Ob das Array doppelte Gruppen-IDs enthält.
-
Ob die Array-Größe den Wert von
Process.maxgroupsüberschreitet.
Verwenden Sie diesen Aufruf, um ein sortiertes und eindeutiges Array zu erhalten.
Process.groups.uniq.sort
Source
static VALUE
proc_setgroups(VALUE obj, VALUE ary)
{
int ngroups, i;
rb_gid_t *groups;
VALUE tmp;
PREPARE_GETGRNAM;
Check_Type(ary, T_ARRAY);
ngroups = RARRAY_LENINT(ary);
if (ngroups > maxgroups())
rb_raise(rb_eArgError, "too many groups, %d max", maxgroups());
groups = ALLOCV_N(rb_gid_t, tmp, ngroups);
for (i = 0; i < ngroups; i++) {
VALUE g = RARRAY_AREF(ary, i);
groups[i] = OBJ2GID1(g);
}
FINISH_GETGRNAM;
if (setgroups(ngroups, groups) == -1) /* ngroups <= maxgroups */
rb_sys_fail(0);
ALLOCV_END(tmp);
return proc_getgroups(obj);
}
Setzt die ergänzende Gruppen-Zugriffsliste auf das gegebene Array von Gruppen-IDs.
Process.groups # => [0, 1, 2, 3, 4, 6, 10, 11, 20, 26, 27] Process.groups = [27, 6, 10, 11] # => [27, 6, 10, 11] Process.groups # => [27, 6, 10, 11]
Source
static VALUE
proc_initgroups(VALUE obj, VALUE uname, VALUE base_grp)
{
if (initgroups(StringValueCStr(uname), OBJ2GID(base_grp)) != 0) {
rb_sys_fail(0);
}
return proc_getgroups(obj);
}
Setzt die ergänzende Gruppen-Zugriffsliste; die neue Liste enthält
-
Die Gruppen-IDs der Gruppen, zu denen der Benutzer
usernamegehört. -
Die Gruppen-ID
gid.
Beispiel
Process.groups # => [0, 1, 2, 3, 4, 6, 10, 11, 20, 26, 27] Process.initgroups('me', 30) # => [30, 6, 10, 11] Process.groups # => [30, 6, 10, 11]
Nicht auf allen Plattformen verfügbar.
Source
static VALUE
proc_rb_f_kill(int c, const VALUE *v, VALUE _)
{
return rb_f_kill(c, v);
}
Sendet ein Signal an jeden durch ids angegebenen Prozess (es muss mindestens eine ID angegeben werden); gibt die Anzahl der gesendeten Signale zurück.
Für jede gegebene id, wenn id
-
Positiv ist, wird das Signal an den Prozess gesendet, dessen Prozess-ID
idist. -
Null ist, wird das Signal an alle Prozesse in der aktuellen Prozessgruppe gesendet.
-
Negativ ist, wird das Signal an eine systemabhängige Sammlung von Prozessen gesendet.
Das Argument signal gibt das zu sendende Signal an; das Argument kann sein
-
Eine Ganzzahl-Signalnummer: z. B.
-29,0,29. -
Ein Signalname (String), mit oder ohne führendes
'SIG'und mit oder ohne ein weiteres vorangestelltes Minuszeichen ('-'): z. B.-
'SIGPOLL'. -
'POLL', -
'-SIGPOLL'. -
'-POLL'.
-
-
Ein Symbol, mit oder ohne führendes
'SIG'und mit oder ohne ein weiteres vorangestelltes Minuszeichen ('-'): z. B.-
:SIGPOLL. -
:POLL. -
:'-SIGPOLL'. -
:'-POLL'.
-
Wenn signal
-
Eine nicht-negative Ganzzahl oder ein Signalname oder -symbol ohne vorangestelltes
'-'ist, wird jeder Prozess mit der Prozess-IDidsignalisiert. -
Eine negative Ganzzahl oder ein Signalname oder -symbol mit vorangestelltem
'-'ist, wird jede Prozessgruppe mit der Gruppen-IDidsignalisiert.
Verwenden Sie die Methode Signal.list, um zu sehen, welche Signale von Ruby auf der zugrunde liegenden Plattform unterstützt werden; die Methode gibt einen Hash der String-Namen und nicht-negativen Ganzzahlwerte der unterstützten Signale zurück. Die Größe und der Inhalt des zurückgegebenen Hash variieren stark je nach Plattform.
Zusätzlich ist das Signal 0 nützlich, um zu bestimmen, ob der Prozess existiert.
Beispiel
pid = fork do Signal.trap('HUP') { puts 'Ouch!'; exit } # ... do some work ... end # ... Process.kill('HUP', pid) Process.wait
Ausgabe
Ouch!
Ausnahmen
-
Löst Errno::EINVAL oder
RangeErroraus, wennsignaleine Ganzzahl, aber ungültig ist. -
Löst
ArgumentErroraus, wennsignalein String oder Symbol, aber ungültig ist. -
Löst Errno::ESRCH oder
RangeErroraus, wenn eine deridsungültig ist. -
Löst Errno::EPERM aus, wenn die benötigten Berechtigungen nicht erzwungen werden.
In den letzten beiden Fällen können Signale an einige Prozesse gesendet worden sein.
Source
static VALUE
proc_s_last_status(VALUE mod)
{
return rb_last_status_get();
}
Gibt ein Process::Status-Objekt zurück, das den zuletzt beendeten Kindprozess im aktuellen Thread repräsentiert, oder nil, wenn keiner vorhanden ist.
Process.spawn('ruby', '-e', 'exit 13') Process.wait Process.last_status # => #<Process::Status: pid 14396 exit 13> Process.spawn('ruby', '-e', 'exit 14') Process.wait Process.last_status # => #<Process::Status: pid 4692 exit 14> Process.spawn('ruby', '-e', 'exit 15') # 'exit 15' has not been reaped by #wait. Process.last_status # => #<Process::Status: pid 4692 exit 14> Process.wait Process.last_status # => #<Process::Status: pid 1380 exit 15>
Source
static VALUE
proc_getmaxgroups(VALUE obj)
{
return INT2FIX(maxgroups());
}
Gibt die maximale Anzahl von Gruppen-IDs zurück, die in der ergänzenden Gruppen-Zugriffsliste zulässig sind.
Process.maxgroups # => 32
Source
static VALUE
proc_setmaxgroups(VALUE obj, VALUE val)
{
int ngroups = FIX2INT(val);
int ngroups_max = get_sc_ngroups_max();
if (ngroups <= 0)
rb_raise(rb_eArgError, "maxgroups %d should be positive", ngroups);
if (ngroups > RB_MAX_GROUPS)
ngroups = RB_MAX_GROUPS;
if (ngroups_max > 0 && ngroups > ngroups_max)
ngroups = ngroups_max;
_maxgroups = ngroups;
return INT2FIX(_maxgroups);
}
Setzt die maximale Anzahl von Gruppen-IDs, die in der ergänzenden Gruppen-Zugriffsliste zulässig sind.
Source
static VALUE
proc_get_pid(VALUE _)
{
return get_pid();
}
Gibt die Prozess-ID des aktuellen Prozesses zurück.
Process.pid # => 15668
Source
static VALUE
proc_get_ppid(VALUE _)
{
return get_ppid();
}
Gibt die Prozess-ID des Elternteils des aktuellen Prozesses zurück.
puts "Pid is #{Process.pid}." fork { puts "Parent pid is #{Process.ppid}." }
Ausgabe
Pid is 271290. Parent pid is 271290.
Gibt auf bestimmten Plattformen möglicherweise keinen vertrauenswürdigen Wert zurück.
Source
static VALUE
proc_setpgid(VALUE obj, VALUE pid, VALUE pgrp)
{
rb_pid_t ipid, ipgrp;
ipid = NUM2PIDT(pid);
ipgrp = NUM2PIDT(pgrp);
if (setpgid(ipid, ipgrp) < 0) rb_sys_fail(0);
return INT2FIX(0);
}
Setzt die Prozessgruppen-ID für den durch die Prozess-ID pid angegebenen Prozess auf pgid.
Nicht auf allen Plattformen verfügbar.
Source
static VALUE
proc_setpgrp(VALUE _)
{
/* check for posix setpgid() first; this matches the posix */
/* getpgrp() above. It appears that configure will set SETPGRP_VOID */
/* even though setpgrp(0,0) would be preferred. The posix call avoids */
/* this confusion. */
#ifdef HAVE_SETPGID
if (setpgid(0,0) < 0) rb_sys_fail(0);
#elif defined(HAVE_SETPGRP) && defined(SETPGRP_VOID)
if (setpgrp() < 0) rb_sys_fail(0);
#endif
return INT2FIX(0);
}
Entspricht setpgid(0, 0).
Nicht auf allen Plattformen verfügbar.
Source
static VALUE
proc_setpriority(VALUE obj, VALUE which, VALUE who, VALUE prio)
{
int iwhich, iwho, iprio;
iwhich = NUM2INT(which);
iwho = NUM2INT(who);
iprio = NUM2INT(prio);
if (setpriority(iwhich, iwho, iprio) < 0)
rb_sys_fail(0);
return INT2FIX(0);
}
Siehe Process.getpriority.
Beispiele
Process.setpriority(Process::PRIO_USER, 0, 19) # => 0 Process.setpriority(Process::PRIO_PROCESS, 0, 19) # => 0 Process.getpriority(Process::PRIO_USER, 0) # => 19 Process.getpriority(Process::PRIO_PROCESS, 0) # => 19
Nicht auf allen Plattformen verfügbar.
Source
static VALUE
proc_setproctitle(VALUE process, VALUE title)
{
return ruby_setproctitle(title);
}
Setzt den Prozess-Titel, der in der Befehlszeile von ps(1) erscheint. Nicht unbedingt auf allen Plattformen wirksam. Es wird keine Ausnahme ausgelöst, unabhängig vom Ergebnis, noch wird NotImplementedError ausgelöst, auch wenn die Plattform das Feature nicht unterstützt.
Der Aufruf dieser Methode hat keinen Einfluss auf den Wert von $0.
Process.setproctitle('myapp: worker #%d' % worker_id)
Diese Methode erschien erstmals in Ruby 2.1, um eine globale variable freie Möglichkeit zur Änderung des Prozess-Titels zu bieten.
Source
static VALUE
proc_setrlimit(int argc, VALUE *argv, VALUE obj)
{
VALUE resource, rlim_cur, rlim_max;
struct rlimit rlim;
rb_check_arity(argc, 2, 3);
resource = argv[0];
rlim_cur = argv[1];
if (argc < 3 || NIL_P(rlim_max = argv[2]))
rlim_max = rlim_cur;
rlim.rlim_cur = rlimit_resource_value(rlim_cur);
rlim.rlim_max = rlimit_resource_value(rlim_max);
if (setrlimit(rlimit_resource_type(resource), &rlim) < 0) {
rb_sys_fail("setrlimit");
}
return Qnil;
}
Setzt die Limits für den aktuellen Prozess für die gegebene resource auf cur_limit (soft limit) und max_limit (hard limit); gibt nil zurück.
Das Argument resource gibt die Ressource an, deren Limits gesetzt werden sollen; das Argument kann als Symbol, als String oder als Konstante beginnend mit Process::RLIMIT_ (z. B. :CORE, 'CORE' oder Process::RLIMIT_CORE) angegeben werden.
Die verfügbaren und unterstützten Ressourcen sind systemabhängig und können (hier als Symbole ausgedrückt) Folgendes umfassen:
-
:AS: Gesamtverfügbarer Speicher (Bytes) (SUSv3, NetBSD, FreeBSD, OpenBSD außer 4.4BSD-Lite). -
:CORE: Core-Größe (Bytes) (SUSv3). -
:CPU: CPU-Zeit (Sekunden) (SUSv3). -
:DATA:Data-Segment (Bytes) (SUSv3). -
:FSIZE:File-Größe (Bytes) (SUSv3). -
:MEMLOCK: Gesamtgröße für mlock(2) (Bytes) (4.4BSD, GNU/Linux). -
:MSGQUEUE: Zuweisung für POSIX-Nachrichtenwarteschlangen (Bytes) (GNU/Linux). -
:NICE: Obergrenze für den Nice(2)-Wert eines Prozesses (Nummer) (GNU/Linux). -
:NOFILE:File-Deskriptoren (Nummer) (SUSv3). -
:NPROC: Anzahl der Prozesse für den Benutzer (Nummer) (4.4BSD, GNU/Linux). -
:NPTS: Anzahl der Pseudo-Terminals (Nummer) (FreeBSD). -
:RSS: Residenter Speicherplatz (Bytes) (4.2BSD, GNU/Linux). -
:RTPRIO: Obergrenze für die Echtzeitpriorität des Prozesses (Nummer) (GNU/Linux). -
:RTTIME: CPU-Zeit für Echtzeitprozesse (us) (GNU/Linux). -
:SBSIZE: Alle Socket-Puffer (Bytes) (NetBSD, FreeBSD). -
:SIGPENDING: Anzahl der erlaubten anstehenden Signale (Signale) (GNU/Linux). -
:STACK: Stack-Größe (Bytes) (SUSv3).
Die Argumente cur_limit und max_limit können sein
-
Ganzzahlen (
max_limitsollte nicht kleiner alscur_limitsein). -
Symbol:SAVED_MAX, String'SAVED_MAX'oder KonstanteProcess::RLIM_SAVED_MAX: gespeichertes maximales Limit. -
Symbol:SAVED_CUR, String'SAVED_CUR'oder KonstanteProcess::RLIM_SAVED_CUR: gespeichertes aktuelles Limit. -
Symbol:INFINITY, String'INFINITY'oder KonstanteProcess::RLIM_INFINITY: kein Limit für die Ressource.
Dieses Beispiel hebt das Soft-Limit der Core-Größe auf das Hard-Limit an, um den Core-Dump zu ermöglichen.
Process.setrlimit(:CORE, Process.getrlimit(:CORE)[1])
Nicht auf allen Plattformen verfügbar.
Source
static VALUE
proc_setsid(VALUE _)
{
rb_pid_t pid;
pid = setsid();
if (pid < 0) rb_sys_fail(0);
return PIDT2NUM(pid);
}
Etabliert den aktuellen Prozess als neuen Sitzungs- und Prozessgruppen-Leader ohne steuerndes Terminal; gibt die Sitzungs-ID zurück.
Process.setsid # => 27422
Nicht auf allen Plattformen verfügbar.
Source
static VALUE
rb_f_spawn(int argc, VALUE *argv, VALUE _)
{
rb_pid_t pid;
char errmsg[CHILD_ERRMSG_BUFLEN] = { '\0' };
VALUE execarg_obj, fail_str;
struct rb_execarg *eargp;
execarg_obj = rb_execarg_new(argc, argv, TRUE, FALSE);
eargp = rb_execarg_get(execarg_obj);
fail_str = eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name;
pid = rb_execarg_spawn(execarg_obj, errmsg, sizeof(errmsg));
if (pid == -1) {
int err = errno;
rb_exec_fail(eargp, err, errmsg);
RB_GC_GUARD(execarg_obj);
rb_syserr_fail_str(err, fail_str);
}
#if defined(HAVE_WORKING_FORK) || defined(HAVE_SPAWNV)
return PIDT2NUM(pid);
#else
return Qnil;
#endif
}
Erzeugt einen neuen Kindprozess, indem im Kindprozess eine der folgenden Aktionen ausgeführt wird.
-
Übergabe des Strings
command_linean die Shell. -
Aufrufen der ausführbaren Datei unter
exe_path.
Diese Methode hat potenzielle Sicherheitslücken, wenn sie mit nicht vertrauenswürdigen Eingaben aufgerufen wird. Siehe Command Injection.
Gibt die Prozess-ID (pid) des neuen Prozesses zurück, ohne auf dessen Fertigstellung zu warten.
Um Zombie-Prozesse zu vermeiden, sollte der Elternprozess entweder aufrufen
-
Process.wait, um die Beendigungsstatus seiner Kinder zu sammeln. -
Process.detach, um Desinteresse an ihrem Status zu registrieren.
Der neue Prozess wird mithilfe des exec-Systemaufrufs erstellt; er kann einige seiner Umgebung vom aufrufenden Programm erben (möglicherweise einschließlich offener Dateideskriptoren).
Das Argument env, falls gegeben, ist ein Hash, der sich auf ENV für den neuen Prozess auswirkt; siehe Ausführungsumgebung.
Das Argument options ist ein Hash von Optionen für den neuen Prozess; siehe Ausführungsoptionen.
Das erste erforderliche Argument ist eines der folgenden
-
command_line, wenn es ein String ist und wenn es mit einem Shell-reservierten Wort oder einem speziellen Built-in beginnt oder wenn es ein oder mehrere Meta-Zeichen enthält. -
exe_pathandernfalls.
Argument command_line
Das Zeichenkettenargument command_line ist eine Befehlszeile, die an eine Shell übergeben wird; sie muss mit einem reservierten Shell-Wort beginnen, mit einem speziellen Built-in beginnen oder Metazeichen enthalten.
spawn('if true; then echo "Foo"; fi') # => 798847 # Shell reserved word. Process.wait # => 798847 spawn('exit') # => 798848 # Built-in. Process.wait # => 798848 spawn('date > /tmp/date.tmp') # => 798879 # Contains meta character. Process.wait # => 798849 spawn('date > /nop/date.tmp') # => 798882 # Issues error message. Process.wait # => 798882
Die Befehlszeile kann auch Argumente und Optionen für den Befehl enthalten.
spawn('echo "Foo"') # => 799031 Process.wait # => 799031
Ausgabe
Foo
Siehe Ausführungs-Shell für Details zur Shell.
Löst eine Ausnahme aus, wenn der neue Prozess nicht ausgeführt werden konnte.
Argument exe_path
Das Argument exe_path ist eines der folgenden:
-
Der Zeichenkettenpfad zu einer ausführbaren Datei, die aufgerufen werden soll.
-
Ein 2-elementiges Array, das den Pfad zu einer aufzurufenden ausführbaren Datei und den String enthält, der als Name des ausgeführten Prozesses verwendet werden soll.
spawn('/usr/bin/date') # Path to date on Unix-style system. Process.wait
Ausgabe
Mon Aug 28 11:43:10 AM CDT 2023
Ruby ruft die ausführbare Datei direkt auf. Diese Form verwendet keine Shell; siehe Argumente args für Einschränkungen.
Wenn ein oder mehrere args angegeben sind, ist jedes ein Argument oder eine Option, die an die ausführbare Datei übergeben werden soll.
spawn('echo', 'C*') # => 799392 Process.wait # => 799392 spawn('echo', 'hello', 'world') # => 799393 Process.wait # => 799393
Ausgabe
C* hello world
Löst eine Ausnahme aus, wenn der neue Prozess nicht ausgeführt werden konnte.
Source
VALUE
rb_proc_times(VALUE obj)
{
VALUE utime, stime, cutime, cstime, ret;
#if defined(RUSAGE_SELF) && defined(RUSAGE_CHILDREN)
struct rusage usage_s, usage_c;
if (getrusage(RUSAGE_SELF, &usage_s) != 0 || getrusage(RUSAGE_CHILDREN, &usage_c) != 0)
rb_sys_fail("getrusage");
utime = DBL2NUM((double)usage_s.ru_utime.tv_sec + (double)usage_s.ru_utime.tv_usec/1e6);
stime = DBL2NUM((double)usage_s.ru_stime.tv_sec + (double)usage_s.ru_stime.tv_usec/1e6);
cutime = DBL2NUM((double)usage_c.ru_utime.tv_sec + (double)usage_c.ru_utime.tv_usec/1e6);
cstime = DBL2NUM((double)usage_c.ru_stime.tv_sec + (double)usage_c.ru_stime.tv_usec/1e6);
#else
const double hertz = (double)get_clk_tck();
struct tms buf;
times(&buf);
utime = DBL2NUM(buf.tms_utime / hertz);
stime = DBL2NUM(buf.tms_stime / hertz);
cutime = DBL2NUM(buf.tms_cutime / hertz);
cstime = DBL2NUM(buf.tms_cstime / hertz);
#endif
ret = rb_struct_new(rb_cProcessTms, utime, stime, cutime, cstime);
RB_GC_GUARD(utime);
RB_GC_GUARD(stime);
RB_GC_GUARD(cutime);
RB_GC_GUARD(cstime);
return ret;
}
Gibt eine Process::Tms-Struktur zurück, die Benutzer- und System-CPU-Zeiten für den aktuellen Prozess und seine Kindprozesse enthält.
Process.times # => #<struct Process::Tms utime=55.122118, stime=35.533068, cutime=0.0, cstime=0.002846>
Die Genauigkeit ist plattformdefiniert.
Source
static VALUE
proc_getuid(VALUE obj)
{
rb_uid_t uid = getuid();
return UIDT2NUM(uid);
}
Gibt die (reale) Benutzer-ID des aktuellen Prozesses zurück.
Process.uid # => 1000
Source
static VALUE
proc_setuid(VALUE obj, VALUE id)
{
rb_uid_t uid;
check_uid_switch();
uid = OBJ2UID(id);
#if defined(HAVE_SETRESUID)
if (setresuid(uid, -1, -1) < 0) rb_sys_fail(0);
#elif defined HAVE_SETREUID
if (setreuid(uid, -1) < 0) rb_sys_fail(0);
#elif defined HAVE_SETRUID
if (setruid(uid) < 0) rb_sys_fail(0);
#elif defined HAVE_SETUID
{
if (geteuid() == uid) {
if (setuid(uid) < 0) rb_sys_fail(0);
}
else {
rb_notimplement();
}
}
#endif
return id;
}
Setzt die (Benutzer-)Benutzer-ID für den aktuellen Prozess auf new_uid.
Process.uid = 1000 # => 1000
Nicht auf allen Plattformen verfügbar.
Source
static VALUE
proc_m_wait(int c, VALUE *v, VALUE _)
{
return proc_wait(c, v);
}
Wartet, bis ein geeigneter Kindprozess beendet wird, gibt dessen Prozess-ID zurück und setzt $? auf ein Process::Status-Objekt, das Informationen über diesen Prozess enthält. Welches Kind gewartet wird, hängt vom Wert der gegebenen pid ab.
-
Positive Ganzzahl: Wartet auf den Kindprozess, dessen Prozess-ID
pidist.pid0 = Process.spawn('ruby', '-e', 'exit 13') # => 230866 pid1 = Process.spawn('ruby', '-e', 'exit 14') # => 230891 Process.wait(pid0) # => 230866 $? # => #<Process::Status: pid 230866 exit 13> Process.wait(pid1) # => 230891 $? # => #<Process::Status: pid 230891 exit 14> Process.wait(pid0) # Raises Errno::ECHILD
-
0: Wartet auf jeden Kindprozess, dessen Gruppen-ID mit der des aktuellen Prozesses übereinstimmt.parent_pgpid = Process.getpgid(Process.pid) puts "Parent process group ID is #{parent_pgpid}." child0_pid = fork do puts "Child 0 pid is #{Process.pid}" child0_pgid = Process.getpgid(Process.pid) puts "Child 0 process group ID is #{child0_pgid} (same as parent's)." end child1_pid = fork do puts "Child 1 pid is #{Process.pid}" Process.setpgid(0, Process.pid) child1_pgid = Process.getpgid(Process.pid) puts "Child 1 process group ID is #{child1_pgid} (different from parent's)." end retrieved_pid = Process.wait(0) puts "Process.wait(0) returned pid #{retrieved_pid}, which is child 0 pid." begin Process.wait(0) rescue Errno::ECHILD => x puts "Raised #{x.class}, because child 1 process group ID differs from parent process group ID." end
Ausgabe
Parent process group ID is 225764. Child 0 pid is 225788 Child 0 process group ID is 225764 (same as parent's). Child 1 pid is 225789 Child 1 process group ID is 225789 (different from parent's). Process.wait(0) returned pid 225788, which is child 0 pid. Raised Errno::ECHILD, because child 1 process group ID differs from parent process group ID.
-
-1(Standard): Wartet auf jeden Kindprozess.parent_pgpid = Process.getpgid(Process.pid) puts "Parent process group ID is #{parent_pgpid}." child0_pid = fork do puts "Child 0 pid is #{Process.pid}" child0_pgid = Process.getpgid(Process.pid) puts "Child 0 process group ID is #{child0_pgid} (same as parent's)." end child1_pid = fork do puts "Child 1 pid is #{Process.pid}" Process.setpgid(0, Process.pid) child1_pgid = Process.getpgid(Process.pid) puts "Child 1 process group ID is #{child1_pgid} (different from parent's)." sleep 3 # To force child 1 to exit later than child 0 exit. end child_pids = [child0_pid, child1_pid] retrieved_pid = Process.wait(-1) puts child_pids.include?(retrieved_pid) retrieved_pid = Process.wait(-1) puts child_pids.include?(retrieved_pid)
Ausgabe
Parent process group ID is 228736. Child 0 pid is 228758 Child 0 process group ID is 228736 (same as parent's). Child 1 pid is 228759 Child 1 process group ID is 228759 (different from parent's). true true
-
Weniger als
-1: Wartet auf jeden Kindprozess, dessen Prozessgruppen-ID-pidist.parent_pgpid = Process.getpgid(Process.pid) puts "Parent process group ID is #{parent_pgpid}." child0_pid = fork do puts "Child 0 pid is #{Process.pid}" child0_pgid = Process.getpgid(Process.pid) puts "Child 0 process group ID is #{child0_pgid} (same as parent's)." end child1_pid = fork do puts "Child 1 pid is #{Process.pid}" Process.setpgid(0, Process.pid) child1_pgid = Process.getpgid(Process.pid) puts "Child 1 process group ID is #{child1_pgid} (different from parent's)." end sleep 1 retrieved_pid = Process.wait(-child1_pid) puts "Process.wait(-child1_pid) returned pid #{retrieved_pid}, which is child 1 pid." begin Process.wait(-child1_pid) rescue Errno::ECHILD => x puts "Raised #{x.class}, because there's no longer a child with process group id #{child1_pid}." end
Ausgabe
Parent process group ID is 230083. Child 0 pid is 230108 Child 0 process group ID is 230083 (same as parent's). Child 1 pid is 230109 Child 1 process group ID is 230109 (different from parent's). Process.wait(-child1_pid) returned pid 230109, which is child 1 pid. Raised Errno::ECHILD, because there's no longer a child with process group id 230109.
Das Argument flags sollte als eine der folgenden Konstanten oder als logisches OR beider angegeben werden.
-
Process::WNOHANG: Blockiert nicht, wenn kein Kindprozess verfügbar ist. -
Process::WUNTRACED: Kann einen angehaltenen Kindprozess zurückgeben, auch wenn er noch nicht gemeldet wurde.
Nicht alle Flags sind auf allen Plattformen verfügbar.
Löst Errno::ECHILD aus, wenn kein geeigneter Kindprozess vorhanden ist.
Nicht auf allen Plattformen verfügbar.
Process.waitpid ist ein Alias für Process.wait.
Source
static VALUE
proc_wait2(int argc, VALUE *argv, VALUE _)
{
VALUE pid = proc_wait(argc, argv);
if (NIL_P(pid)) return Qnil;
return rb_assoc_new(pid, rb_last_status_get());
}
Ähnlich wie Process.waitpid, gibt aber ein Array zurück, das die Kindprozess-pid und den Process::Status-status enthält.
pid = Process.spawn('ruby', '-e', 'exit 13') # => 309581 Process.wait2(pid) # => [309581, #<Process::Status: pid 309581 exit 13>]
Process.waitpid2 ist ein Alias für Process.wait2.
Source
static VALUE
proc_waitall(VALUE _)
{
VALUE result;
rb_pid_t pid;
int status;
result = rb_ary_new();
rb_last_status_clear();
for (pid = -1;;) {
pid = rb_waitpid(-1, &status, 0);
if (pid == -1) {
int e = errno;
if (e == ECHILD)
break;
rb_syserr_fail(e, 0);
}
rb_ary_push(result, rb_assoc_new(PIDT2NUM(pid), rb_last_status_get()));
}
return result;
}
Wartet auf alle Kinder, gibt ein Array von 2-elementigen Arrays zurück; jedes Unterarray enthält die Ganzzahl-PID und den Process::Status-Status für einen der wiederhergestellten Kindprozesse.
pid0 = Process.spawn('ruby', '-e', 'exit 13') # => 325470 pid1 = Process.spawn('ruby', '-e', 'exit 14') # => 325495 Process.waitall # => [[325470, #<Process::Status: pid 325470 exit 13>], [325495, #<Process::Status: pid 325495 exit 14>]]
Source
static VALUE
proc_m_wait(int c, VALUE *v, VALUE _)
{
return proc_wait(c, v);
}
Wartet, bis ein geeigneter Kindprozess beendet wird, gibt dessen Prozess-ID zurück und setzt $? auf ein Process::Status-Objekt, das Informationen über diesen Prozess enthält. Welches Kind gewartet wird, hängt vom Wert der gegebenen pid ab.
-
Positive Ganzzahl: Wartet auf den Kindprozess, dessen Prozess-ID
pidist.pid0 = Process.spawn('ruby', '-e', 'exit 13') # => 230866 pid1 = Process.spawn('ruby', '-e', 'exit 14') # => 230891 Process.wait(pid0) # => 230866 $? # => #<Process::Status: pid 230866 exit 13> Process.wait(pid1) # => 230891 $? # => #<Process::Status: pid 230891 exit 14> Process.wait(pid0) # Raises Errno::ECHILD
-
0: Wartet auf jeden Kindprozess, dessen Gruppen-ID mit der des aktuellen Prozesses übereinstimmt.parent_pgpid = Process.getpgid(Process.pid) puts "Parent process group ID is #{parent_pgpid}." child0_pid = fork do puts "Child 0 pid is #{Process.pid}" child0_pgid = Process.getpgid(Process.pid) puts "Child 0 process group ID is #{child0_pgid} (same as parent's)." end child1_pid = fork do puts "Child 1 pid is #{Process.pid}" Process.setpgid(0, Process.pid) child1_pgid = Process.getpgid(Process.pid) puts "Child 1 process group ID is #{child1_pgid} (different from parent's)." end retrieved_pid = Process.wait(0) puts "Process.wait(0) returned pid #{retrieved_pid}, which is child 0 pid." begin Process.wait(0) rescue Errno::ECHILD => x puts "Raised #{x.class}, because child 1 process group ID differs from parent process group ID." end
Ausgabe
Parent process group ID is 225764. Child 0 pid is 225788 Child 0 process group ID is 225764 (same as parent's). Child 1 pid is 225789 Child 1 process group ID is 225789 (different from parent's). Process.wait(0) returned pid 225788, which is child 0 pid. Raised Errno::ECHILD, because child 1 process group ID differs from parent process group ID.
-
-1(Standard): Wartet auf jeden Kindprozess.parent_pgpid = Process.getpgid(Process.pid) puts "Parent process group ID is #{parent_pgpid}." child0_pid = fork do puts "Child 0 pid is #{Process.pid}" child0_pgid = Process.getpgid(Process.pid) puts "Child 0 process group ID is #{child0_pgid} (same as parent's)." end child1_pid = fork do puts "Child 1 pid is #{Process.pid}" Process.setpgid(0, Process.pid) child1_pgid = Process.getpgid(Process.pid) puts "Child 1 process group ID is #{child1_pgid} (different from parent's)." sleep 3 # To force child 1 to exit later than child 0 exit. end child_pids = [child0_pid, child1_pid] retrieved_pid = Process.wait(-1) puts child_pids.include?(retrieved_pid) retrieved_pid = Process.wait(-1) puts child_pids.include?(retrieved_pid)
Ausgabe
Parent process group ID is 228736. Child 0 pid is 228758 Child 0 process group ID is 228736 (same as parent's). Child 1 pid is 228759 Child 1 process group ID is 228759 (different from parent's). true true
-
Weniger als
-1: Wartet auf jeden Kindprozess, dessen Prozessgruppen-ID-pidist.parent_pgpid = Process.getpgid(Process.pid) puts "Parent process group ID is #{parent_pgpid}." child0_pid = fork do puts "Child 0 pid is #{Process.pid}" child0_pgid = Process.getpgid(Process.pid) puts "Child 0 process group ID is #{child0_pgid} (same as parent's)." end child1_pid = fork do puts "Child 1 pid is #{Process.pid}" Process.setpgid(0, Process.pid) child1_pgid = Process.getpgid(Process.pid) puts "Child 1 process group ID is #{child1_pgid} (different from parent's)." end sleep 1 retrieved_pid = Process.wait(-child1_pid) puts "Process.wait(-child1_pid) returned pid #{retrieved_pid}, which is child 1 pid." begin Process.wait(-child1_pid) rescue Errno::ECHILD => x puts "Raised #{x.class}, because there's no longer a child with process group id #{child1_pid}." end
Ausgabe
Parent process group ID is 230083. Child 0 pid is 230108 Child 0 process group ID is 230083 (same as parent's). Child 1 pid is 230109 Child 1 process group ID is 230109 (different from parent's). Process.wait(-child1_pid) returned pid 230109, which is child 1 pid. Raised Errno::ECHILD, because there's no longer a child with process group id 230109.
Das Argument flags sollte als eine der folgenden Konstanten oder als logisches OR beider angegeben werden.
-
Process::WNOHANG: Blockiert nicht, wenn kein Kindprozess verfügbar ist. -
Process::WUNTRACED: Kann einen angehaltenen Kindprozess zurückgeben, auch wenn er noch nicht gemeldet wurde.
Nicht alle Flags sind auf allen Plattformen verfügbar.
Löst Errno::ECHILD aus, wenn kein geeigneter Kindprozess vorhanden ist.
Nicht auf allen Plattformen verfügbar.
Process.waitpid ist ein Alias für Process.wait.
Source
static VALUE
proc_wait2(int argc, VALUE *argv, VALUE _)
{
VALUE pid = proc_wait(argc, argv);
if (NIL_P(pid)) return Qnil;
return rb_assoc_new(pid, rb_last_status_get());
}
Ähnlich wie Process.waitpid, gibt aber ein Array zurück, das die Kindprozess-pid und den Process::Status-status enthält.
pid = Process.spawn('ruby', '-e', 'exit 13') # => 309581 Process.wait2(pid) # => [309581, #<Process::Status: pid 309581 exit 13>]
Process.waitpid2 ist ein Alias für Process.wait2.
Source
static VALUE
proc_warmup(VALUE _)
{
RB_VM_LOCKING() {
rb_gc_prepare_heap();
}
return Qtrue;
}
Benachrichtigt die Ruby-virtuelle Maschine, dass die Boot-Sequenz abgeschlossen ist und es nun ein guter Zeitpunkt ist, die Anwendung zu optimieren. Dies ist nützlich für langlebige Anwendungen.
Diese Methode sollte am Ende des Anwendung-Boots aufgerufen werden. Wenn die Anwendung in einem Pre-Forking-Modell bereitgestellt wird, sollte Process.warmup im ursprünglichen Prozess vor dem ersten Fork aufgerufen werden.
Die tatsächlich durchgeführten Optimierungen sind vollständig implementierungsspezifisch und können sich in Zukunft ohne Vorankündigung ändern.
Auf CRuby führt Process.warmup Folgendes aus:
-
Führt eine Haupt-GC durch (
GC). -
Kompaktiert den Heap.
-
Befördert alle überlebenden Objekte in die alte Generation.
-
Berechnet den Codebereich aller Strings im Voraus.
-
Gibt alle leeren Heap-Seiten frei und erhöht den Zähler der allokierbaren Seiten um die Anzahl der freigegebenen Seiten.
-
Ruft
malloc_trimauf, falls verfügbar, um leere Malloc-Seiten freizugeben.