Navigation
 Startseite
 Fachbücher
 Anzeigenmarkt
 Forum
 Webmaster News
 Script Newsletter
 Kontakt
 Script Installation
 Php
 Php Tutorials
 Webhoster Vergleich
 Impressum

Community-Bereich
 kostenlos Registrieren
 Anmelden
 Benutzerliste

Script Datenbank
 Script Archiv
 Script Top 20
 Screenshots
 Testberichte

Suche
 

Unsere Php Scripts
 Counter Script
 Umfrage Script
 Bilder Upload Script
 Terminverwaltung
 Simple PHP Forum
 RSS Grabber

Script Mods
 phpBB Adsense Mode

Tools und Generatoren
 .htpasswd Generator
 md5 Generator
 base64 Generator
 Markdown to HTML
 Colorpicker
 Unix timestamp Tool
 TLD Liste
 Webkatalog‑Verzeichnis

Partner
 Sprüche Treff

Hosterplus.de
Bekommen Sie Speicherplatz (Webspace), Domains...
https://www.Hosterplus.de
Artfiles.de
Bietet Serviceorientierte...
https://www.Artfiles.de
 
 
 

PHP usleep(): Präzise Zeitverzögerungen in Mikrosekunden meistern

Sie befinden sich: Home > Php Tutorial > PHP Script verzögern in...

PHP Script verzögern in Mikrosekunden


Eintrag am:  18.08.2010
Hits / Besucher:  5905
Sprache:  Deutsch
Kategorie:  Einsteiger Tutorials
Tutorial Art:  eigenes
Eingetragen von   schubertmedia schubertmedia
 
Beschreibung

Wie kann man in PHP wirklich präzise, kurze Pausen realisieren? Wer mit Mikrosekunden arbeiten muss, etwa beim Throttling von Anfragen, in Hardware-nahen Scripten oder bei der Simulation von Wartezeiten, stößt schnell auf die Funktion usleep(). Sie erlaubt es, die Skriptausführung punktgenau um winzige Zeitspannen zu verzögern. In der Praxis gibt es dabei zahlreiche Details zu beachten, von der korrekten Umrechnung in Mikrosekunden bis zur Frage, wann du usleep() besser nicht in Webseiten einsetzen solltest.

Modernes Titelbild mit digitaler Uhr, Mikrosekunden-Anzeige, Binärcode und PHP-Logo für einen Blogartikel zu PHP usleep().

 

Was ist usleep() und wofür wird es verwendet?

Die Funktion usleep() pausiert die Ausführung eines PHP-Skripts für eine angegebene Anzahl von Mikrosekunden. Eine Mikrosekunde entspricht einem Millionstel einer Sekunde. Im Gegensatz zu sleep(), das nur volle Sekunden akzeptiert, steuerst du mit usleep() die Pausenlänge deutlich feiner.

Umrechnungstabelle: Mikrosekunden, Millisekunden, Sekunden

Die Verwechslung von Mikrosekunden und Millisekunden ist der häufigste Fehler bei usleep(). Diese Tabelle hilft dir, den richtigen Wert schnell abzulesen:

Gewünschte PauseMillisekundenusleep()-Wert
50 ms5050.000
100 ms100100.000
250 ms250250.000
500 ms500500.000
1 Sekunde1.0001.000.000

Syntax und Parameter

Die Syntax von usleep() ist denkbar einfach. Die Funktion erwartet genau einen Parameter und gibt keinen Wert zurück.

usleep(int $iMikrosekunden): void

Der Parameter $iMikrosekunden muss ein Integer-Wert größer oder gleich 0 sein. Bei negativen Werten wirft PHP seit Version 8.0 einen ValueError. Bei sehr großen Werten (mehr als 1.000.000) solltest du überlegen, ob sleep() nicht die bessere Wahl ist.

<?php

echo "Start: " . date('H:i:s') . "\n";
usleep(500000); // 500 ms Pause
echo "Ende: " . date('H:i:s') . "\n";
?>

Praktische Anwendungsfälle

usleep() kommt vor allem in CLI-Scripten und Backend-Prozessen zum Einsatz. Hier sind die wichtigsten Szenarien mit vollständigen Codebeispielen.

Rate Limiting bei API-Anfragen

Viele APIs begrenzen die Anzahl der Anfragen pro Zeiteinheit. Mit usleep() kannst du zwischen den Requests eine definierte Pause einlegen, um das Limit nicht zu überschreiten.

<?php

$aUrls = [
'https://api.example.com/users/1',
'https://api.example.com/users/2',
'https://api.example.com/users/3',
'https://api.example.com/users/4',
'https://api.example.com/users/5',
];

foreach ($aUrls as $iIndex => $sUrl) {
$sAntwort = file_get_contents($sUrl);
echo ($iIndex + 1) . " von " . count($aUrls);
echo " abgerufen\n";

if ($iIndex < count($aUrls) - 1) {
usleep(200000); // 200 ms zwischen Requests
}
}
echo "Fertig!\n";
?>

Retry mit exponentiellem Backoff

Wenn ein API-Aufruf fehlschlägt, ist es sinnvoll, nicht sofort erneut anzufragen, sondern die Wartezeit mit jedem Versuch zu erhöhen. Dieses Pattern nennt sich exponentieller Backoff und verhindert, dass du einen überlasteten Server noch stärker belastest.

<?php

function fetchMitRetry(string $sUrl, int $iMaxVersuche = 3): string|false
{
for ($i = 1; $i <= $iMaxVersuche; $i++) {
$sAntwort = @file_get_contents($sUrl);
if ($sAntwort !== false) {
return $sAntwort;
}
if ($i < $iMaxVersuche) {
$iWartezeit = $i * $i * 100000;
/* 100ms, 400ms, 900ms */
usleep($iWartezeit);
echo "Versuch $i fehlgeschlagen,";
echo " warte " . ($iWartezeit / 1000);
echo " ms\n";
}
}
return false;
}

$sErgebnis = fetchMitRetry('https://api.example.com/data');
?>

Fortschrittsanzeige in CLI-Scripten

Für Fortschrittsbalken oder Statusmeldungen in der Kommandozeile brauchst du kurze Pausen, damit die Ausgabe für den Benutzer lesbar bleibt.

<?php

$iGesamt = 50;
for ($i = 1; $i <= $iGesamt; $i++) {
$iProzent = (int) ($i / $iGesamt * 100);
echo "\rFortschritt: $iProzent%";
usleep(50000); // 50 ms pro Schritt
}
echo "\nAbgeschlossen!\n";
?>

Warnung: usleep() in Webseiten blockiert den Server

Dieser Punkt ist so wichtig, dass er einen eigenen Abschnitt verdient: Verwende usleep() (und sleep()) nicht leichtfertig in Webseiten.

Jeder Aufruf von usleep() blockiert den aktuellen PHP-Prozess. Bei Apache ist das ein Thread, bei PHP-FPM ein Worker-Slot. Während der Pause kann dieser Prozess keine anderen Anfragen bedienen. Wenn viele gleichzeitige Requests usleep() aufrufen, gehen dem Server die verfügbaren Worker aus, und die Seite wird für alle Besucher langsam oder unerreichbar.

Besser: Verwende für zeitgesteuerte Aufgaben in Webanwendungen Cron-Jobs, Message Queues (z.B. mit Redis oder RabbitMQ) oder asynchrone Verarbeitung. usleep() gehört in CLI-Scripte und Backend-Prozesse, nicht in Controller oder API-Endpoints.

Maximale Ausführungszeit und Plattformunterschiede

Ein wichtiger Unterschied zwischen Linux und Windows: Auf Linux und macOS zählt die Zeit, die in usleep() oder sleep() verbracht wird, nicht zur max_execution_time. PHP misst dort nur die tatsächliche CPU-Zeit. Auf Windows hingegen zählt die gesamte Wanduhrzeit inklusive Pausen zur max_execution_time.

Das bedeutet: Ein Script mit usleep(5000000) (5 Sekunden Pause) und einer max_execution_time von 3 Sekunden läuft auf Linux problemlos durch, bricht aber auf Windows mit einem Timeout ab. Teste dein Script auf der Zielplattform, wenn du mit langen Pausen arbeitest.

Output Buffering und Flush

Wenn du während einer Schleife mit usleep() Ausgaben machen willst, beachte, dass PHP die Ausgabe standardmäßig puffert. Ohne explizites Flushing siehst du die Ausgabe erst nach Ablauf des gesamten Scripts.

<?php

/* Ausgabe sofort anzeigen (CLI) */
for ($i = 1; $i <= 5; $i++) {
echo "Schritt $i\n";
if (ob_get_level() > 0) {
ob_flush();
}
flush();
usleep(500000); // 500 ms
}
?>

Verwandte Funktionen im Vergleich

PHP bietet mehrere Funktionen für Pausen mit unterschiedlicher Präzision. Hier ein Überblick, wann du welche verwenden solltest.

FunktionAuflösungEinsatzgebiet
sleep()SekundenLängere Pausen ab 1 Sekunde
usleep()MikrosekundenKurze Pausen im Millisekunden-Bereich
time_nanosleep()NanosekundenHöchste Präzision, liefert Restzeit bei Unterbrechung
time_sleep_until()Sekunden (float)Pause bis zu einem exakten Zeitpunkt

time_sleep_until() für exaktes Timing

Wenn du in einer Schleife exakt alle 100 ms einen Tick auslösen willst, ist usleep() nicht ideal: Die Verarbeitungszeit innerhalb der Schleife addiert sich, und die Ticks driften mit der Zeit ab. time_sleep_until() löst das Problem, indem du einen exakten Zeitpunkt als Ziel angibst.

<?php

$fIntervall = 0.1; // 100 ms
$fNaechsterTick = microtime(true) + $fIntervall;

for ($i = 0; $i < 10; $i++) {
echo "Tick $i um " . microtime(true) . "\n";

/* Exakt bis zum nächsten Zeitpunkt warten */
time_sleep_until($fNaechsterTick);
$fNaechsterTick += $fIntervall;
}
?>

So bleiben die Ticks gleichmäßig verteilt, auch wenn die Verarbeitung innerhalb der Schleife unterschiedlich lange dauert. Die Scriptlaufzeit mit microtime() zu messen hilft dir, die tatsächliche Präzision zu überprüfen.

time_nanosleep() für höchste Genauigkeit

Für Situationen, in denen selbst Mikrosekunden zu grob sind, bietet PHP time_nanosleep(). Die Funktion erwartet zwei Parameter: Sekunden und Nanosekunden. Der Vorteil gegenüber usleep(): Bei Unterbrechung durch ein Signal gibt sie die verbleibende Restzeit zurück.

<?php

/* 0,5 Sekunden = 500.000.000 Nanosekunden */
$mErgebnis = time_nanosleep(0, 500000000);

if ($mErgebnis === true) {
echo "Pause abgeschlossen";
} elseif (is_array($mErgebnis)) {
echo "Unterbrochen! Restzeit: ";
echo $mErgebnis['seconds'] . " s, ";
echo $mErgebnis['nanoseconds'] . " ns";
}
?>

Signal Handling in CLI-Daemons

In lang laufenden CLI-Prozessen (Daemons, Worker) möchtest du eventuell auf Signale wie SIGTERM reagieren können, auch während einer Pause. Mit pcntl_async_signals() und pcntl_signal() kannst du einen Signal-Handler registrieren, der die usleep()-Pause unterbricht.

<?php

/* Nur unter Linux/macOS, nicht Windows */
pcntl_async_signals(true);

$bLauft = true;
pcntl_signal(SIGTERM, function () use (&$bLauft) {
echo "SIGTERM empfangen, beende...\n";
$bLauft = false;
});

while ($bLauft) {
echo "Arbeite...\n";
usleep(1000000); // 1 Sekunde
}
echo "Sauber beendet.\n";
?>

Ohne Signal-Handling würde ein kill-Befehl den Prozess sofort beenden, ohne dass aufgeräumt werden kann. Mit dem Handler hast du die Chance, offene Datenbankverbindungen zu schließen oder temporäre Dateien zu löschen.

Häufig gestellte Fragen (FAQ)

Die folgenden Fragen tauchen bei der Arbeit mit usleep() regelmäßig auf.

Kann ich usleep(0) verwenden?

Ja, usleep(0) ist gültig und gibt die Kontrolle kurz an das Betriebssystem ab. In der Praxis bewirkt es aber keine spürbare Pause.

Läuft usleep() auf allen Plattformen?

Ja, usleep() funktioniert unter Linux, macOS und Windows. Die tatsächliche Genauigkeit hängt aber vom Betriebssystem ab. Unter Windows ist die minimale Auflösung typischerweise 15-16 ms, während Linux und macOS deutlich feinere Pausen ermöglichen.

Wie messe ich die echte Pausendauer?

Miss die Zeit vor und nach dem usleep()-Aufruf mit microtime(true) und berechne die Differenz. So siehst du, wie genau die Pause tatsächlich war.

Was ist der Unterschied zwischen Mikrosekunden und Millisekunden?

1 Millisekunde = 1.000 Mikrosekunden. Für eine Pause von 100 Millisekunden brauchst du also usleep(100000) und nicht usleep(100). Diese Verwechslung ist der häufigste Fehler.

Kann usleep() durch Signale unterbrochen werden?

Ja, auf Unix-Systemen kann ein Signal die Pause vorzeitig beenden. Wenn du die exakte Restzeit brauchst, verwende time_nanosleep(), die bei Unterbrechung ein Array mit der verbleibenden Zeit zurückgibt.

Wann sollte ich time_nanosleep() statt usleep() verwenden?

Wenn du höchste Präzision brauchst oder die Restzeit bei Unterbrechung auswerten willst. Für die meisten Anwendungsfälle wie Rate Limiting oder Fortschrittsanzeigen reicht usleep() völlig aus.

Fazit

usleep() ist das richtige Werkzeug für präzise, kurze Pausen im Millisekundenbereich. Für Rate Limiting, Retry-Logik und CLI-Fortschrittsanzeigen ist die Funktion unverzichtbar. Denke aber daran, dass usleep() den aktuellen PHP-Prozess blockiert. In Webseiten solltest du deshalb auf Alternativen wie Cron-Jobs oder Message Queues setzen.

Für längere Pausen ab einer Sekunde ist sleep() die einfachere Wahl, und für exakte Intervalle in Schleifen bietet time_sleep_until() die beste Präzision. Nutze die Fehlermeldungssteuerung, um Deprecation-Warnings bei negativen Werten (ab PHP 8.0) frühzeitig zu erkennen.

 

Tags:

 

Bücherregal mit drei Büchern: 'PHP 4 - Grundlagen und Profiwissen' von Hanser Verlag, 'Webdesign in a Nutshell' von O'Reilly Verlag, und 'Webgestaltung' von Galileo Computing.