Socket_Set_Block Nachdem Socket auf den Blockierungsmodus gesetzt ist, blockieren IO -Operationen (wie Socket_read , Socket_Write ) den aktuellen Vorgang oder Thread, bis die gelesenen Daten abgeschlossen ist oder das Schreiben erfolgreich ist. Dies ist sehr einfach und effektiv in Szenarien mit einem Threaden oder mit niedriger Konsequenz, aber in Szenarien mit hoher Konsequenz spiegeln sich die Risiken hauptsächlich in den folgenden Punkten wider:
Blockade verursacht Ressourcenbeschäftigung <br> Der Blockierungsmodus macht das Programm, das eine Anfrage bearbeitet, die Ausführung für einen Moment nicht fortgesetzt werden kann, insbesondere wenn sich das Netzwerk verzögert oder der Peer langsam reagiert. Der Prozess "steckt" in der IO -Stufe, wodurch eine große Anzahl von Prozessen wartet und die Ressourcen besetzt werden.
Verringerte Durchsatz, erhöhte Reaktionslatenz <br> Wenn eine große Anzahl von Verbindungen blockiert ist, kann der Server keine neuen Verbindungsanforderungen rechtzeitig verarbeiten, was zu einer längeren Reaktionszeit und einer schlechteren Benutzererfahrung führt.
Die Anzahl der Threads/Prozesse ist begrenzt <br> Die Parallelitätsfunktion des Servers ist durch die Anzahl der verfügbaren Threads oder Prozesse begrenzt. Blockiervorgänge machen diese Fäden oder Prozesse in einem Wartezustand, was sehr einfach ist, die Fadenpool erschöpft zu machen.
Deadlock -Risiko <br> Wenn beim Blockieren und Warten die Konkurrenz um gegenseitig exklusive Ressourcen beteiligt ist, ist es einfach, Deadlocks zu verursachen und ein Programm zu verursachen.
Durch Aufrufen von Socket_Set_NonBlock , um den Socket auf den Nicht-Blocking-Modus festzulegen, blockiert IO-Operationen den aktuellen Prozess nicht, sondern werden sofort zurückgegeben. In Kombination mit ereignisgesteuerten Mechanismen (wie Auswahl , Umfrage oder Libvent in PHP-Erweiterungen) kann die gleichzeitige Verarbeitungsfähigkeiten effektiv verbessern.
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 8080);
socket_listen($socket);
socket_set_nonblock($socket);
while (true) {
$client = @socket_accept($socket);
if ($client === false) {
// Keine neue Verbindung,Setzen Sie die Schleife fort
usleep(10000); // Eine Pause machen,reduzierenCPUBelegung
continue;
}
// An den Kunden socket Setzen Sie auch nicht blockiert
socket_set_nonblock($client);
// Beim Lesen oder Schreiben von Daten,Kombiniert socket_select Hörstatus
}
?>
Socket_Select kann den Les- und Schreibstatus mehrerer Steckdosen anhören, eine einzelne Verbindung vermeiden und die Effizienz des Servers verbessern, um mehrere Verbindungen zu verarbeiten.
<?php
$read = [$socket];
$write = null;
$except = null;
if (socket_select($read, $write, $except, 0, 200000)) {
foreach ($read as $readSocket) {
if ($readSocket === $socket) {
$client = socket_accept($socket);
socket_set_nonblock($client);
// Hinzufügen, um zuzuhören
} else {
$data = socket_read($readSocket, 1024);
if ($data === false || $data === '') {
socket_close($readSocket);
// Entfernen Sie aus der Liste der Liste
} else {
// Verarbeitungsdaten
}
}
}
}
?>
Mit Hilfe asynchroner Frameworks wie Smoke und ReactPHP kann die Blockierung vollständig vermieden werden, und eine große Anzahl gleichzeitiger Verbindungen kann asynchron verarbeitet werden, was die Leistung erheblich verbessert.
<?php
use Swoole\Coroutine\Http\Server;
$server = new Server("0.0.0.0", 9501);
$server->handle('/', function ($request, $response) {
$response->end("Hello, Swoole!");
});
$server->start();
?>
Verwenden Sie Multi-Process- oder Multi-Threading vernünftigerweise, um unabhängige Arbeiterfäden oder -prozesse Blockiervorgänge zuzuweisen, um die Blockierung des Hauptfadens zu vermeiden.
Risikopunkte | Antwortmaßnahmen |
---|---|
Durch das Blockieren warten der Prozess auf die Verwendung von Ressourcen | Verwenden Sie den nicht blockierenden Modus- oder Event-Treiber |
Antwortlatenz und Durchsatzabfall | Verwenden Sie Socket_Select , um auf mehrere Verbindungen zu hören |
Fadenpool erschöpft | Verwenden Sie Multi-Thread-/Multi-Process-Pools, um Stress zu teilen |
Deadlock -Risiko | Entwerfen Sie eine angemessene Strategie für den Zugang zur Ressourcenzugriff, um sich gegenseitig ausschließende Sackgassen zu vermeiden |
Versuchen Sie in einer hohen Genauigkeitsumgebung, die Verwendung von Blockieren von Steckdosen zu vermeiden und nicht blockierende, ereignisgesteuerte Modelle und asynchrone Rahmenbedingungen zu nutzen, um den effizienten und stabilen Betrieb von PHP-Programmen sicherzustellen.