Frage

Manchmal, wenn ich ein Programm in Linux schreiben und stürzt aufgrund eines Fehlers von einer Art, wird es eine unterbrechungsfreie Prozess und weiter geworden läuft immer, bis ich meinen Computer neu starten (auch wenn ich mich abmelde). Meine Fragen sind:

  • Was bewirkt, dass ein Prozess nicht unterbrechbare werden?
  • Wie kann ich verhindern, dass nicht passiert?
  • Dies ist wahrscheinlich eine dumme Frage, aber gibt es eine Möglichkeit, es zu unterbrechen, ohne meinen Computer neu zu starten?
War es hilfreich?

Lösung

eine unterbrechungsfreie Prozess ist ein Prozess, der in einem Systemaufruf (Kernel-Funktion), die nicht durch ein Signal unterbrochen werden kann, passiert werden.

Um zu verstehen, was das bedeutet, Sie müssen das Konzept eines unterbrechbare Systemaufruf verstehen. Das klassische Beispiel ist read(). Dies ist ein Systemaufruf, der eine lange Zeit (in Sekunden) dauern kann, da es möglicherweise eine Festplatte hochgefahren oder beweglichen Köpfe beinhalten können. Während des größten Teils dieser Zeit wird der Prozess schlafen, auf der Hardware zu blockieren.

Während der Prozess in den Systemaufruf schläft, kann es eine UNIX asynchrones Signal (sagen wir, SIGTERM) empfangen, dann geschieht Folgendes:

  • Das System ruft Ausfahrten vorzeitig, und eingerichtet ist, zurückzukehren -EINTR auf Anwenderseite.
  • Die Signal-Handler ausgeführt wird.
  • Wenn der Prozess noch läuft, wird es den Rückgabewert aus dem Systemaufruf, und es kann den gleichen Anruf wieder machen.

früh aus dem Systemaufruf Rückkehr ermöglicht den Code Benutzerraum sofort sein Verhalten in Reaktion auf das Signal zu verändern. Zum Beispiel endet sauber in Reaktion auf SIGINT oder SIGTERM.

Auf der anderen Seite werden einige Systemaufrufe nicht erlaubt auf diese Weise unterbrochen werden. Wenn das System ruft Stände aus irgendeinem Grunde kann der Prozess auf unbestimmte Zeit bleibt in diesem Zustand unkillable.

LWN lief eine schöne Artikel , die dieses Thema im Juli berühren.

die ursprüngliche Frage zu beantworten:

  • Wie dies zu verhindern: herauszufinden, welche Treiber Probleme verursacht, und entweder nicht mehr verwenden, oder einen Kernel-Hacker werden und es beheben

  • .
  • Wie eine unterbrechungsfreie Prozess zu töten, ohne einen Neustart: irgendwie den Systemaufruf beenden machen. Häufig ist die effektivste Art und Weise, dies zu tun, ohne den Netzschalter zu schlagen ist das Netzkabel zu ziehen. Sie können auch ein Kernel-Hacker werden und der Fahrer TASK_KILLABLE nutzen machen, wie sie in der LWN Artikel erläutert.

Andere Tipps

Wenn ein Prozess auf Benutzermodus ist, kann es jederzeit unterbrochen werden (Schaltmodus auf Kernel). Wenn der Kern in dem Benutzermodus zurückkehrt, überprüft er, ob es irgendwelche anstehenden Signale (einschließlich denen, die den Prozess, wie SIGTERM SIGKILL und werden verwendet, um zu töten). Das bedeutet, ein Prozess kann nur bei der Rückkehr in dem Benutzermodus getötet werden.

Der Grund, ein Prozess kann nicht im Kernel-Modus getötet wird, ist, dass es könnte potenziell korrupt die Kernel-Strukturen von allen anderen Prozessen in der gleichen Maschine (die gleiche Art und Weise einen Thread zu töten können potenziell korrupte Datenstrukturen von anderen Threads in dem verwendeten gleicher Prozess).

Wenn der Kernel etwas tun muss, das eine lange Zeit in Anspruch nehmen könnte (Warten auf ein Rohr von einem anderen Prozess geschrieben oder warten auf die Hardware etwas, zum Beispiel zu tun), es schläft selbst als Schlafmarkierung und ruft den Scheduler umschalten auf einen anderen Prozess (wenn es keine nicht-Schlaf Prozess ist, schaltet sie auf einen „Dummy“ Verfahren, das die CPU sagt etwas zu verlangsamen und sitzt in einer Schleife - die Leerlaufschleife).

Wenn ein Signal an einen Schlaf Prozess gesendet wird, hat sie aufgeweckt werden, bevor sie die User-Space zurückkehren werden und somit das anliegende Signal verarbeiten. Hier haben wir den Unterschied zwischen den zwei Arten von Schlaf:

  • TASK_INTERRUPTIBLE, der unterbrechbare Schlaf. Wenn eine Aufgabe mit dieser Flagge markiert ist, es schläft, kann aber durch Signale geweckt. Dies bedeutet, dass der Code, der die Aufgabe als Schlaf markierte ein mögliche Signal erwartet, und nachdem er wacht denn es wird prüfen und Rückkehr aus dem Systemaufruf. Nachdem das Signal verarbeitet wird, kann der Systemaufruf automatisch neu gestartet werden, möglicherweise (und ich werde nicht ins Detail gehen, wie das funktioniert).
  • TASK_UNINTERRUPTIBLE, die unterbrechungsfreie Schlaf. Wenn eine Aufgabe mit dieser Flagge markiert, es wird nicht erwartet, andere von etwas aufgeweckt werden als das, was es für wartet, sei es, weil es nicht leicht neu gestartet werden kann, oder weil Programme den Systemaufruf erwarten Atom zu sein. Dies kann auch für Betten verwendet werden, dafür bekannt, sehr kurz sein.

TASK_KILLABLE (in dem Artikel verknüpft LWN erwähnt durch ddaa Antwort) ist eine neue Variante.

Diese beantworten Ihre erste Frage. Was Ihre zweite Frage: Sie sind nicht unterbrechungsfrei schlafen vermeiden können, sind sie eine normale Sache (geschieht es zum Beispiel schreibt jedes Mal, wenn ein Prozess / liest von / auf die Platte); sollten sie jedoch nur einen Bruchteil einer Sekunde dauern. Wenn sie viel länger dauern, bedeutet dies in der Regel ein Hardware-Problem (oder ein Gerätetreiber Problem, das das gleiche an den Kernel sieht), wobei der Gerätetreiber für die Hardware warten, etwas zu tun, was nie passieren wird. Es kann auch bedeuten, Sie NFS verwenden und den NFS-Server ausgefallen ist (es wird für den Server warten, sich zu erholen, können Sie auch die „intr“ Option verwenden können, um das Problem zu vermeiden)

.

Schließlich ist der Grund, warum Sie sich nicht erholen können, ist aus dem gleichen Grund wartet der Kernel bis zur Rückkehr in dem Benutzermodus ein Signal oder töten, um den Prozess zu liefern: es würde möglicherweise korrupt die Datenstrukturen des Kernels (Code auf unterbrechbarer Schlaf warten können eine Fehlermeldung das sagt es den User-space zurückzukehren, wo der Prozess getötet werden kann;. Code auf einem unterbrechungsfreien Schlaf wartet keine Störungen erwartet)

unterbrechungsfreie Prozesse der Regel für E / A-Anschluss an einer Seite Fehler warten.

Bedenken Sie:

  • Der Thread versucht, auf eine Seite zuzugreifen, die nicht im Kern (entweder eine ausführbare, das bedarf geladen ist, wird eine Seite der anonymen Speicher, der aus wurde ausgetauscht oder eine Mmap () 'd-Datei, der Bedarf geladen wird, die sind viel die gleiche Sache)
  • Der Kernel ist nun (versuchen zu) es in laden
  • Der Prozess kann nicht fortgesetzt werden, bis die Seite verfügbar ist.

Der Prozess / Task kann in diesem Zustand nicht unterbrochen werden, da es keine Signale nicht verarbeiten kann; wenn es so wäre, wäre eine andere Seite Fehler passieren und es würde wieder, wo es war.

Als ich „Prozess“ sage, meine ich wirklich „Aufgabe“, die unter Linux (2.6) übersetzt in etwa „Faden“, die kann oder auch nicht eine individuelle „Thread-Gruppe“ Eintrag in / proc

In einigen Fällen kann es für eine lange Zeit warten. Ein typisches Beispiel hierfür wäre, wenn die ausführbare Datei oder mmap'd Datei auf einem Netzwerk-Dateisystem ist, wo der Server ausgefallen ist. Wenn das I / O schließlich erfolgreich ist, wird die Aufgabe fortzusetzen. Wenn es schließlich ausfällt, wird die Aufgabe im Allgemeinen eine SIGBUS oder etwas bekommen.

Um Ihre dritte Frage: Ich glaube, Sie können die unterbrechungsfreie Prozesse töten, indem Sie sudo kill -HUP 1. Es wird init neu starten, ohne die laufenden Prozesse zu beenden und nach dem Laufen, meine unterbrechungsfreie Prozesse gegangen waren.

Wenn Sie über einen „Zombie“ Prozess sprechen (die als „Zombie“ in ps Ausgang bezeichnet wird), dann ist dies eine harmlose Aufzeichnung in der Liste Prozess warten, dass jemand seinen Rückkehrcode zu sammeln und sicher ignoriert werden kann .

Könnten Sie bitte beschreiben, was und „nicht unterbrechbare Prozess“ für Sie? Ist es die „kill -9“ und glücklich tuckert entlang überlebt? Wenn das der Fall ist, dann ist es auf einigen syscall stecken, die in einem gewissen Fahrer steckt, und Sie sind mit diesem Prozess bis Neustart stecken (und manchmal ist es besser, einen Neustart bald) oder Entladen von relevanten Treiber (was unwahrscheinlich ist) . Sie könnten versuchen, „strace“ zu verwenden, um herauszufinden, wo Ihr Prozess klemmt und es in Zukunft zu vermeiden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top