Aktueller Standort: Startseite> Neueste Artikel> Möchten Sie die Priorität von Kinderprozessen kontrollieren? Sehen Sie, wie Sie Proc_nice verwenden, um es in PHP zu implementieren

Möchten Sie die Priorität von Kinderprozessen kontrollieren? Sehen Sie, wie Sie Proc_nice verwenden, um es in PHP zu implementieren

gitbox 2025-08-26

In hohen Parallelitäts- oder Batch -Verarbeitungsszenarien möchten wir oft nicht, dass einige Hintergrundaufgaben die CPU "essen" und die Reaktion auf externe Dienste beeinflussen. Das Betriebssystem hat Priorität zur Anpassung des aktuellen Prozesses bereitgestellt. Um den untergeordneten Prozess zu steuern, können Sie ihn im Gabelkindprozess aufrufen oder es für eine bestimmte PID in Kombination mit proc_open () und posix_setPriority () anpassen. Dieser Artikel enthält praktische Paradigmen, Grubenpunkte und Fehlerbehebungsvorschläge.

Cheat: Bei Unix -ähnlichen Systemen beträgt der schöne Wertebereich in der Regel -20 (höchste Priorität) bis 19 (am niedrigsten) und die Standardeinstellung 0.

  • Gewöhnliche Benutzer können nur die Schönheit erhöhen (Priorität reduzieren) , beispielsweise von 0 → 10.

  • Die Priorität auf einen negativen Wert (z. B. -5) erfordert normalerweise Wurzelfunktionen oder cap_sys_nice .


Szenario 1: Nach PCNTL_FORK () , "Abschreibungen und Lauf" im Kinderprozess

Wenn Sie pcntl_fork () verwenden, um einen untergeordneten Prozess abzuleiten, ist es am direktesten, Proc_nice () im untergeordneten Prozess anzurufen. Beispiel: Der übergeordnete Prozess ist für die Annahme von Arbeitsplätzen verantwortlich, während der Kinderprozess starke Arbeit leistet, aber die Priorität reduziert, um die Verlangsamung der Gesamtsituation zu vermeiden.

 <span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-keyword">declare</span></span><span>(strict_types=</span><span><span class="hljs-number">1</span></span><span>);

</span><span><span class="hljs-comment">// Stellen Sie sicher, dass die Erweiterung aktiviert ist:pcntl、posix(Optional)</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-title function_ invoke__">function_exists</span></span><span>(</span><span><span class="hljs-string">'pcntl_fork'</span></span><span>)) {
    </span><span><span class="hljs-title function_ invoke__">fwrite</span></span><span>(STDERR, </span><span><span class="hljs-string">"pcntl Nicht aktiviert,Nicht demonstrieren\n"</span></span><span>);
    </span><span><span class="hljs-keyword">exit</span></span><span>(</span><span><span class="hljs-number">1</span></span><span>);
}

</span><span><span class="hljs-variable">$pid</span></span><span> = </span><span><span class="hljs-title function_ invoke__">pcntl_fork</span></span><span>();
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$pid</span></span><span> === -</span><span><span class="hljs-number">1</span></span><span>) {
    </span><span><span class="hljs-keyword">throw</span></span><span> </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">RuntimeException</span></span><span>(</span><span><span class="hljs-string">'fork scheitern'</span></span><span>);
}

</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$pid</span></span><span> === </span><span><span class="hljs-number">0</span></span><span>) {
    </span><span><span class="hljs-comment">// --- Subprozess ---</span></span><span>
    </span><span><span class="hljs-comment">// Wille niceness Aus Standard 0 Angepasst an 10(Sogar“freundlich”,Sogar低优先级)</span></span><span>
    </span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-title function_ invoke__">proc_nice</span></span><span>(</span><span><span class="hljs-number">10</span></span><span>)) {
        </span><span><span class="hljs-comment">// scheitern通常意味着Berechtigungen不足或Plattform不支持</span></span><span>
        </span><span><span class="hljs-title function_ invoke__">fwrite</span></span><span>(STDERR, </span><span><span class="hljs-string">"[child] proc_nice scheitern\n"</span></span><span>);
    }

    </span><span><span class="hljs-comment">// Simulation CPU Intensive Arbeit</span></span><span>
    </span><span><span class="hljs-variable">$sum</span></span><span> = </span><span><span class="hljs-number">0</span></span><span>;
    </span><span><span class="hljs-keyword">for</span></span><span> (</span><span><span class="hljs-variable">$i</span></span><span> = </span><span><span class="hljs-number">0</span></span><span>; </span><span><span class="hljs-variable">$i</span></span><span> &lt; </span><span><span class="hljs-number">5_000_000</span></span><span>; </span><span><span class="hljs-variable">$i</span></span><span>++) {
        </span><span><span class="hljs-variable">$sum</span></span><span> += </span><span><span class="hljs-variable">$i</span></span><span>;
    }
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"[child] done, sum=<span class="hljs-subst">{$sum}</span></span></span><span>\n";
    </span><span><span class="hljs-keyword">exit</span></span><span>(</span><span><span class="hljs-number">0</span></span><span>);
} </span><span><span class="hljs-keyword">else</span></span><span> {
    </span><span><span class="hljs-comment">// --- Elternprozess ---</span></span><span>
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"[parent] fork 出Subprozess PID=<span class="hljs-subst">{$pid}</span></span></span><span>\n";
    </span><span><span class="hljs-comment">// Elternprozess继续高优先级工作(Zum Beispiel Antwort HTTP fragen)</span></span><span>
    </span><span><span class="hljs-comment">// 等待Subprozess结束(生产环境Optional择不阻塞,Oder ein Signal verwenden/Rückruf)</span></span><span>
    </span><span><span class="hljs-title function_ invoke__">pcntl_wait</span></span><span>(</span><span><span class="hljs-variable">$status</span></span><span>);
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"[parent] child exit code = "</span></span><span> . </span><span><span class="hljs-title function_ invoke__">pcntl_wexitstatus</span></span><span>(</span><span><span class="hljs-variable">$status</span></span><span>) . </span><span><span class="hljs-string">"\n"</span></span><span>;
}
</span></span>

Wichtige Punkte

  1. proc_nice () wirkt sich auf den aktuellen Prozess aus, so dass es im untergeordneten Prozesscodepfad aufgerufen werden muss.

  2. Die Anpassung an einen positiven Wert (z. B. 10) erfordert normalerweise keine Berechtigungen. Das Festlegen eines negativen Wertes kann fehlschlagen.

  3. Wenn Sie einfach "die Subtask keine Ressourcen schnappen lassen", reicht es oft aus .


Szenario 2: Proc_open () startet einen externen Befehl und passt seine Priorität an

Wenn Sie keine Gabel verwenden, sondern andere Befehle beginnen (z. B. FFMPEG , Konvertieren und PHP, um den Arbeiter selbst auszuführen) müssen Sie die PID erhalten und die Priorität einstellen. proc_get_status () kann die untergeordnete Prozesspid erhalten; Verwenden Sie dann POSIX_SETPRIORITY () (POSIX -Erweiterung), um die PID intuitiver zu betreiben.

 <span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-keyword">declare</span></span><span>(strict_types=</span><span><span class="hljs-number">1</span></span><span>);

</span><span><span class="hljs-variable">$descriptorSpec</span></span><span> = [
    </span><span><span class="hljs-number">0</span></span><span> =&gt; [</span><span><span class="hljs-string">'pipe'</span></span><span>, </span><span><span class="hljs-string">'r'</span></span><span>],
    </span><span><span class="hljs-number">1</span></span><span> =&gt; [</span><span><span class="hljs-string">'pipe'</span></span><span>, </span><span><span class="hljs-string">'w'</span></span><span>],
    </span><span><span class="hljs-number">2</span></span><span> =&gt; [</span><span><span class="hljs-string">'pipe'</span></span><span>, </span><span><span class="hljs-string">'w'</span></span><span>],
];

</span><span><span class="hljs-comment">// Geben Sie ein Beispiel an:Lauf eins CPU Dicht PHP Kinderskript</span></span><span>
</span><span><span class="hljs-variable">$process</span></span><span> = </span><span><span class="hljs-title function_ invoke__">proc_open</span></span><span>(</span><span><span class="hljs-string">'php -r "usleep(3000000);"'</span></span><span>, </span><span><span class="hljs-variable">$descriptorSpec</span></span><span>, </span><span><span class="hljs-variable">$pipes</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-title function_ invoke__">is_resource</span></span><span>(</span><span><span class="hljs-variable">$process</span></span><span>)) {
    </span><span><span class="hljs-keyword">throw</span></span><span> </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">RuntimeException</span></span><span>(</span><span><span class="hljs-string">'proc_open 启动scheitern'</span></span><span>);
}

</span><span><span class="hljs-variable">$status</span></span><span> = </span><span><span class="hljs-title function_ invoke__">proc_get_status</span></span><span>(</span><span><span class="hljs-variable">$process</span></span><span>);
</span><span><span class="hljs-variable">$pid</span></span><span>    = </span><span><span class="hljs-variable">$status</span></span><span>[</span><span><span class="hljs-string">'pid'</span></span><span>] ?? </span><span><span class="hljs-literal">null</span></span><span>;
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"child pid = <span class="hljs-subst">{$pid}</span></span></span><span>\n";

</span><span><span class="hljs-comment">// POSIX Weg:Rechts PID aufstellen nice(Umfang -20~19)</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">function_exists</span></span><span>(</span><span><span class="hljs-string">'posix_setpriority'</span></span><span>) &amp;&amp; </span><span><span class="hljs-variable">$pid</span></span><span>) {
    </span><span><span class="hljs-comment">// WilleSubprozess调为 10(Sogar低优先级)</span></span><span>
    </span><span><span class="hljs-variable">$ok</span></span><span> = @</span><span><span class="hljs-title function_ invoke__">posix_setpriority</span></span><span>(</span><span><span class="hljs-number">10</span></span><span>, </span><span><span class="hljs-variable">$pid</span></span><span>, POSIX_PRIO_PROCESS);
    </span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-variable">$ok</span></span><span>) {
        </span><span><span class="hljs-title function_ invoke__">fwrite</span></span><span>(STDERR, </span><span><span class="hljs-string">"posix_setpriority scheitern(Berechtigungen/Plattform/Zielprozessstatus)\n"</span></span><span>);
    }
} </span><span><span class="hljs-keyword">else</span></span><span> {
    </span><span><span class="hljs-comment">// planen B:Verwenden Sie externe Befehle renice(Linux/Unix)</span></span><span>
    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$pid</span></span><span>) {
        </span><span><span class="hljs-comment">// Beachten:In einigen Umgebungen kann es notwendig sein sudo oder Privileg</span></span><span>
        @</span><span><span class="hljs-title function_ invoke__">shell_exec</span></span><span>(</span><span><span class="hljs-title function_ invoke__">sprintf</span></span><span>(</span><span><span class="hljs-string">'renice +10 -p %d 2&gt;/dev/null'</span></span><span>, </span><span><span class="hljs-variable">$pid</span></span><span>));
    }
}

</span><span><span class="hljs-comment">// Aufräumen</span></span><span>
</span><span><span class="hljs-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$pipes</span></span><span>[</span><span><span class="hljs-number">0</span></span><span>]); </span><span><span class="hljs-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$pipes</span></span><span>[</span><span><span class="hljs-number">1</span></span><span>]); </span><span><span class="hljs-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$pipes</span></span><span>[</span><span><span class="hljs-number">2</span></span><span>]);
</span><span><span class="hljs-variable">$exitCode</span></span><span> = </span><span><span class="hljs-title function_ invoke__">proc_close</span></span><span>(</span><span><span class="hljs-variable">$process</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"child exit code = <span class="hljs-subst">{$exitCode}</span></span></span><span>\n";
</span></span>

Wichtige Punkte

  • Proc_open () gibt einen Griff zurück und passt die Priorität nicht automatisch an. Sie müssen die PID erhalten und manuell verarbeiten.

  • pox_setPriority () ist kontrollierbarer als Renice und hat weniger Unterschiede über Verteilungen hinweg, muss jedoch die POSIX -Erweiterung aktiviert werden.

  • Wenn Sie sich in einer Container- oder Nicht-Root-Umgebung befinden, können Sie nur die Freundlichkeit erhöhen (Priorität reduzieren) .


Szenario 3: Verwenden Sie Nizza / Ionice , um zu starten (am schnellsten)

Wenn Sie nicht in PHP eingestimmen müssen, können Sie die Subprozess auch mit niedriger Priorität direkt auf der Befehlszeilenebene starten:

 <span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-keyword">declare</span></span><span>(strict_types=</span><span><span class="hljs-number">1</span></span><span>);

</span><span><span class="hljs-comment">// CPU freundlich:nice +10</span></span><span>
</span><span><span class="hljs-variable">$cmd</span></span><span> = </span><span><span class="hljs-string">'nice -n 10 php worker.php'</span></span><span>;

</span><span><span class="hljs-comment">// I/O freundlich:ionice class 2(best-effort),level 7(niedrigste)</span></span><span>
</span><span><span class="hljs-variable">$cmd</span></span><span> = </span><span><span class="hljs-string">'ionice -c 2 -n 7 nice -n 10 php worker.php'</span></span><span>;

</span><span><span class="hljs-variable">$proc</span></span><span> = </span><span><span class="hljs-title function_ invoke__">proc_open</span></span><span>(</span><span><span class="hljs-variable">$cmd</span></span><span>, [
    </span><span><span class="hljs-number">0</span></span><span> =&gt; [</span><span><span class="hljs-string">'pipe'</span></span><span>, </span><span><span class="hljs-string">'r'</span></span><span>],
    </span><span><span class="hljs-number">1</span></span><span> =&gt; [</span><span><span class="hljs-string">'pipe'</span></span><span>, </span><span><span class="hljs-string">'w'</span></span><span>],
    </span><span><span class="hljs-number">2</span></span><span> =&gt; [</span><span><span class="hljs-string">'pipe'</span></span><span>, </span><span><span class="hljs-string">'w'</span></span><span>],
], </span><span><span class="hljs-variable">$pipes</span></span><span>);

</span><span><span class="hljs-comment">// ... 省略与上文相同的Aufräumen逻辑</span></span><span>
</span></span>

Hinweis

  • Ionice beeinflusst nur die E/A -Planung (Festplatte), ist oft mit schönem und CPU + E/A -Dualstromgrenze stabiler.

  • Einige Mindestbilder für Container haben möglicherweise keine Ionice und sollten im Bild installiert werden (z. B. das Util-Linux- Paket).


Fehlerbehandlung und Beobachtbarkeit

  1. Rückgabewert und Alarm erkennen

    • proc_nice () gibt true/false zurück. Wenn Sie versagen, zeichnen Sie bitte das Protokoll auf und fügen Sie den Kontext wie posix_geteuid () , Zielwert usw. hinzu.

    • posix_setPriority () In ähnlicher Weise sind Fehler in Ermangelung von Berechtigungen häufig und die PID wurde verlassen .

  2. Zeichnen Sie die tatsächliche Priorität auf

    • Linux kann das schöne Feld von /proc/<pid>/stat lesen oder PS -o PID, NI, CMD -P <PID> -Verifizierung aufrufen.

    • In PHP können Sie ('ps -o pid, ni, cmd -p' (int) $ pid, $ out) das Ergebnis ausführen.

  3. Hierarchische aktuelle Grenze

    • Es ist nur für den CPU -Wettbewerb von Nizza allein effektiv; Wenn immer noch eine Übereinstimmung auftretend ist, überlagern Sie bitte den Warteschlangen-/Token -Eimer (z. B. Redis + Lua) und die Obergrenze des Prozesses .


Plattform- und Berechtigungsdetails

  • Linux/Unix : Die Methode in diesem Artikel ist anwendbar. Nicht privilegierte Benutzer können die Freundlichkeit nur erhöhen ("besser sprechen").

  • Container/Systemdienst : Wenn der Dienst von systemd verwaltet wird, können Sie in der Einheitsdatei festlegen oder AmbientCapabilities = cap_sys_nice gewähren. Der Container kann zu den laufenden Parametern hinzugefügt werden.

  • MacOS : Die Semantik ähnelt Linux-, Renice- und POSIX -Schnittstellen.

  • Windows : Proc_nice () ist nicht verfügbar/nicht effektiv (üblicherweise Rückgabeversagen und Auslöser Warnung). Die Priorität von Windows sollte über Proc_open () + WMIC /PowerShell oder FFI angepasst werden. Es gehört zu verschiedenen Implementierungspfaden und befindet sich nicht in denselben Regeln wie dieser Artikel.


Praktische Vorschläge (Shortnotes)

  • Im untergeordneten Prozess : pcntl_fork () → Kinderprozess proc_nice (10 ~ 15) .

  • Externer Befehl : proc_open ()proc_get_status () , um PID → posix_setPriority ($ nice, $ pid, pox_prio_process) zu erhalten.

  • Ein Shuttle : Fügen Sie vor dem Befehl schöne -n ​​<n> hinzu, und E/A ist dicht mit Ionice gestapelt.

  • Berechtigungen : Negative Werte erfordern Privilegien; Erwägen Sie, SYS_NICE -Funktionen hinzuzufügen oder positive Werte im Container zu verwenden.

  • Überprüfung : Verwenden Sie PS oder Lesen /Proc, um dies zu überprüfen. Protokolle werden für die einfache Rückverfolgbarkeit aufgezeichnet.


Referenzabschnitt: Einkapseln Sie eine Gadget -Funktion "Abschreibungsprozess"

 <span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-keyword">declare</span></span><span>(strict_types=</span><span><span class="hljs-number">1</span></span><span>);

<span class="hljs-comment">/**
 * Wille指定 PID Der Prozess niceness Angepasst an目标值(Standard 10)。
 * zurückkehren true äußern“Sieht erfolgreich aus”(Keine Garantie endgültiger Effekt,Müssen kombiniert werden ps verifizieren)。
 */</span>
</span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">lower_priority</span></span><span>(</span><span><span class="hljs-params"><span class="hljs-keyword">int</span></span></span><span> </span><span><span class="hljs-variable">$pid</span></span><span>, </span><span><span class="hljs-keyword">int</span></span><span> </span><span><span class="hljs-variable">$nice</span></span><span> = </span><span><span class="hljs-number">10</span></span><span>): </span><span><span class="hljs-title">bool</span></span><span>
{
    </span><span><span class="hljs-comment">// Grenzwächter</span></span><span>
    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$nice</span></span><span> &lt; -</span><span><span class="hljs-number">20</span></span><span> || </span><span><span class="hljs-variable">$nice</span></span><span> &gt; </span><span><span class="hljs-number">19</span></span><span>) {
        </span><span><span class="hljs-keyword">throw</span></span><span> </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">InvalidArgumentException</span></span><span>(</span><span><span class="hljs-string">'nice Muss in -20..19 zwischen'</span></span><span>);
    }

    </span><span><span class="hljs-comment">// Erste Wahl POSIX API</span></span><span>
    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">function_exists</span></span><span>(</span><span><span class="hljs-string">'posix_setpriority'</span></span><span>)) {
        </span><span><span class="hljs-variable">$ok</span></span><span> = @</span><span><span class="hljs-title function_ invoke__">posix_setpriority</span></span><span>(</span><span><span class="hljs-variable">$nice</span></span><span>, </span><span><span class="hljs-variable">$pid</span></span><span>, POSIX_PRIO_PROCESS);
        </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$ok</span></span><span>) {
            </span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-literal">true</span></span><span>;
        }
    }

    </span><span><span class="hljs-comment">// Alternative:renice(nur *nix)</span></span><span>
    </span><span><span class="hljs-variable">$ret</span></span><span> = </span><span><span class="hljs-number">0</span></span><span>;
    @</span><span><span class="hljs-title function_ invoke__">exec</span></span><span>(</span><span><span class="hljs-title function_ invoke__">sprintf</span></span><span>(</span><span><span class="hljs-string">'renice %s%d -p %d 2&gt;/dev/null'</span></span><span>,
        </span><span><span class="hljs-variable">$nice</span></span><span> &gt;= </span><span><span class="hljs-number">0</span></span><span> ? </span><span><span class="hljs-string">'+'</span></span><span> : </span><span><span class="hljs-string">''</span></span><span>, </span><span><span class="hljs-variable">$nice</span></span><span>, </span><span><span class="hljs-variable">$pid</span></span><span>
    ), </span><span><span class="hljs-variable">$out</span></span><span>, </span><span><span class="hljs-variable">$ret</span></span><span>);

    </span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-variable">$ret</span></span><span> === </span><span><span class="hljs-number">0</span></span><span>;
}
</span></span>