Was bedeutet “Systemaufruf blockieren”?
In meinem Kurs zu Betriebssystemen studieren wir die Multithread-Programmierung. Ich bin mir nicht sicher, was gemeint ist, wenn ich in meinem Lehrbuch lese: “Es kann zulassen, dass ein anderer Thread ausgeführt wird, wenn ein Thread einen blockierenden Systemaufruf durchführt.”
Ein blockierender Systemaufruf muss warten, bis die Aktion abgeschlossen werden kann. read()
wäre ein gutes Beispiel – wenn keine Eingabe bereit ist, bleibt es dort und wartet, bis eine bereit ist (vorausgesetzt, Sie haben es natürlich nicht auf nicht blockierend gesetzt, in diesem Fall wäre es kein blockierender Systemaufruf ). Während ein Thread auf einen blockierenden Systemaufruf wartet, kann ein anderer Thread natürlich etwas anderes tun.
Bei einem blockierenden Systemaufruf kann der Aufrufer nichts tun, bis der Systemaufruf zurückkehrt. Wenn der Systemaufruf langwierig sein kann (z. B. Datei-IO oder Netzwerk-IO einbeziehen), kann dies eine schlechte Sache sein (z. B. stellen Sie sich einen frustrierten Benutzer vor, der in einer Anwendung auf die Schaltfläche „Abbrechen“ hämmert, die nicht antwortet, weil dieser Thread blockiert ist und auf a wartet Paket aus dem Netzwerk, das nicht ankommt). Um dieses Problem zu umgehen (um nützliche Arbeit zu leisten, während Sie auf die Rückkehr eines blockierenden Systemaufrufs warten), können Sie Threads verwenden – während ein Thread blockiert ist, können die anderen Threads weiterhin nützliche Arbeit leisten.
Die Alternative sind nicht blockierende Systemaufrufe. In diesem Fall kehrt der Systemaufruf (fast) sofort zurück. Bei längeren Systemaufrufen wird das Ergebnis des Systemaufrufs entweder später an den Anrufer gesendet (z. B. als eine Art Ereignis oder Nachricht oder Signal) oder von dem Anrufer später abgefragt. Auf diese Weise können Sie einen einzelnen Thread haben, der darauf wartet, dass viele verschiedene lange Systemaufrufe gleichzeitig ausgeführt werden. und vermeidet den Ärger mit Threads (und Sperren, Race-Bedingungen, den Overhead von Thread-Wechseln usw.). Es erhöht jedoch auch den Aufwand, der mit dem Abrufen und Verarbeiten der Ergebnisse des Systemaufrufs verbunden ist.
Es ist (fast immer) möglich, einen nicht blockierenden Wrapper um einen blockierenden Systemaufruf zu schreiben; wobei der Wrapper einen Thread erzeugt und (fast) sofort zurückkehrt, und der erzeugte Thread den blockierenden Systemaufruf ausführt und entweder die Ergebnisse des Systemaufrufs an den ursprünglichen Aufrufer sendet oder sie dort speichert, wo der ursprüngliche Aufrufer sie abfragen kann.
Es ist auch (fast immer) möglich, einen blockierenden Wrapper um einen nicht blockierenden Systemaufruf zu schreiben; wo der Wrapper den Systemaufruf ausführt und auf die Ergebnisse wartet, bevor er zurückkehrt.
Ich würde vorschlagen, diesen sehr kurzen Text zu lesen:
http://files.mkgnu.net/files/upstare/UPSTARE_RELEASE_0-12-8/manual/html-multi/x755.html
Insbesondere können Sie dort nachlesen, warum das Blockieren von Systemaufrufen bei Threads und nicht nur bei gleichzeitigen Prozessen ein Problem sein kann:
Dies ist besonders problematisch für Anwendungen mit mehreren Threads, da das Blockieren eines Threads bei einem Systemaufruf die Aktualisierung des Codes eines anderen Threads auf unbestimmte Zeit verzögern kann.
Ich hoffe es hilft.