190 votes

Ce qui est un processus sans coupure ?

Parfois quand j’écris un programme sous Linux et il se bloque à cause d’un bug quelconque, il va devenir un processus sans coupure et continuer de fonctionner pour toujours jusqu'à ce que je redémarre mon ordinateur (même si je me connecte). Mes questions sont :

  • Ce qui provoque un processus de devenir sans coupure ?
  • Comment puis-je empêcher que se produise ?
  • C’est probablement une question stupide, mais est-il possible de l’interrompre sans avoir à redémarrer mon ordinateur ?

240voto

ddaa Points 19102

Un sans coupure processus est un processus qui se trouve être dans un appel système (noyau de la fonction) qui ne peut être interrompu par un signal.

Pour comprendre ce que cela signifie, vous avez besoin de comprendre le concept d'un interruptable appel système. L'exemple classique est celui de la lecture(). C'est un appel système qui peut prendre du temps (secondes), car il peut potentiellement impliquer en rotation d'un disque dur, ou de déplacer les têtes. Pendant la plus grande partie de ce temps, le processus sera de dormir, le blocage sur le matériel.

Alors que le processus est endormi dans l'appel système, il peut recevoir un unix asynchrone signal (par exemple, SIGTERM), puis le suivant se produit:

  • Les appels système quitte prématurément, et est configuré pour retour EAGAIN vers l'espace utilisateur.
  • Le gestionnaire de signal est exécuté.
  • Si le processus est toujours en cours d'exécution, il obtient la valeur de retour de l'appel système, et si elle est écrite correctement, elle permet de faire le même appel de nouveau.

Le nœud de la question est que (pour une raison que je ne comprends pas vraiment), l'exécution doit sortir de l'appel système pour l'utilisateur, le gestionnaire de signal pour s'exécuter.

D'autre part, certains appels système ne sont pas autorisés à être interrompu. Si le système des appels stands pour une raison quelconque, le processus peut indéfiniment reste dans ce unkillable état.

LWN, a couru un bel article qui abordait ce sujet en juillet.

Pour répondre à la question initiale:

  • Comment faire pour empêcher que cela se passe: comprendre le pilote qui est à l'origine de vos ennuis, et cessez de l'utiliser, ou devenir un noyau de pirates et de le corriger.

  • Comment tuer une source ininterrompue de processus sans avoir à redémarrer: faire en quelque sorte le système d'appel mettre fin. Souvent la manière la plus efficace de le faire sans frapper l'interrupteur d'alimentation est de tirer le cordon d'alimentation. Vous pouvez aussi devenir un noyau de pirates et de permettre au conducteur d'utiliser TASK_KILLABLE, comme expliqué dans l'article LWN.

68voto

CesarB Points 18048

Lorsqu'un processus est en mode utilisateur, il peut être interrompu à tout moment (passage en mode noyau). Lorsque le noyau renvoie au mode utilisateur, il vérifie s'il y a des signaux en attente (y compris ceux qui sont utilisés pour tuer le processus, comme l' SIGTERM et SIGKILL). Cela signifie qu'un processus peut être tué seulement sur le retour au mode utilisateur.

La raison pour laquelle un processus ne peut pas être tué en mode noyau, c'est qu'il pourrait potentiellement endommager le noyau des structures utilisées par tous les autres processus sur la même machine (de la même façon de tuer un thread peut potentiellement endommager les structures de données utilisées par les autres threads du même processus).

Lorsque le noyau a besoin de faire quelque chose qui pourrait prendre un certain temps (en attente sur un tuyau écrit par un autre processus ou en attente pour le matériel pour faire quelque chose, par exemple), il dort en marquant lui-même comme le sommeil et l'appel à l'ordonnanceur pour passer à un autre processus (si il n'y a pas de non-sommeil processus, elle passe à un "dummy" processus qui indique au processeur de ralentir un peu et se trouve dans une boucle de la boucle d'inactivité).

Si un signal est envoyé à un processus en mode veille, il doit être réveillé avant de il sera de retour à l'espace utilisateur, et donc de processus en attente du signal. Nous avons ici la différence entre les deux types de sommeil:le sommeil

  • TASK_INTERRUPTIBLE, le interruptible de sommeil. Si une tâche est marqué avec ce drapeau, c'est le sommeil, mais peut être réveillé par des signaux. Cela signifie que le code qui a marqué la tâche que dormir attend un signal possible, et après il se réveille, va vérifier et de retour de l'appel système. Après que le signal est traité, l'appel système peut potentiellement être redémarré automatiquement (et je n'entrerai pas dans les détails sur comment ça marche).
  • TASK_UNINTERRUPTIBLE, le secours de sommeil. Si une tâche est marqué avec ce drapeau, il n'attend pas d'être réveillé par rien d'autre que ce qu'il attend, soit parce qu'il ne peut pas facilement être redémarré, ou parce que les programmes attendons l'appel système atomique. Cela peut aussi être utilisé pour dort connu pour être très court.

TASK_KILLABLE (mentionné dans l'article LWN liés par ddaa de réponse) est une nouvelle variante.

Ceci répond à votre première question. Quant à votre deuxième question: vous ne pouvez pas éviter de secours dort, ils sont une chose normale (il arrive, par exemple, à chaque fois qu'un processus de lectures/écritures à partir de/vers le disque); toutefois, ils devraient durer qu'une fraction de seconde. Si elles durent beaucoup plus longtemps, cela signifie généralement un problème matériel (ou un pilote de périphérique problème, qui semble la même pour le noyau), où le pilote de périphérique est en attente pour le matériel pour faire quelque chose qui n'arrivera jamais. Il peut également signifier que vous êtes à l'aide de NFS et le serveur NFS est en bas (il est en attente pour le serveur pour récupérer; vous pouvez également utiliser la fonction "intr" option pour éviter le problème).

Enfin, la raison pour laquelle vous ne pouvez pas récupérer est la même raison, le noyau attend jusqu'à ce que le retour au mode utilisateur afin d'obtenir un signal ou tuer le processus: il risquerait de corrompre le noyau de structures de données (code en attente sur un interruptible sommeil peut recevoir une erreur qui lui dit de retourner à l'utilisateur de l'espace, où le processus peut être tué; code en attente sur une source ininterrompue de sommeil ne s'attend à aucun message d'erreur).

33voto

MarkR Points 37178

Sans coupure processus sont souvent en attente d'e/S, à la suite d'une défaillance de page.

Réfléchissez à ceci:

  • Le thread tente d'accéder à une page qui n'est pas dans la base (soit un exécutable qui est la demande bien chargé, une page de la mémoire anonyme qui a été échangé, ou un mmap()'d fichier qui est chargé de la demande, qui sont bien de la même chose)
  • Le noyau est maintenant (essayer de) le charger dans
  • Le processus ne peut pas continuer jusqu'à ce que la page est disponible.

La tâche ne peut pas être interrompu dans cet état, parce qu'il ne peut pas gérer des signaux; si elle l'a fait, une autre page de faute qui allait arriver, et il serait là où il était.

Quand je dis "processus", je veux dire vraiment "tâche", ce qui sous Linux (2.6) se traduit approximativement par "fil" qui peut ou peut ne pas avoir une personne de "groupe de thread" entrée dans /proc

Dans certains cas, il peut être en attente pendant une longue période. Un exemple typique de ce serait l'endroit où le fichier exécutable ou mmap avais fichier est sur un système de fichier réseau où le serveur a échoué. Si l'I/O finalement réussit, la tâche de continuer. Si elle échoue finalement, la tâche sera généralement obtenir un SIGBUS ou quelque chose.

-3voto

ADEpt Points 4405

Pourriez-vous décrire ce et "sans coupure processus"? Il ne survit à la "kill -9" et heureusement souffle? Si c'est le cas, alors il est coincé sur certains syscall, qui est coincé dans un conducteur, et vous êtes coincé avec ce processus jusqu'à redémarrer (et parfois il est préférable de redémarrer bientôt) ou le déchargement d'un pilote concerné (ce qui est peu probable). Vous pouvez essayer d'utiliser "strace" pour savoir où votre processus est bloqué et l'éviter à l'avenir.

Mais si vous parlez d'un "zombie" (qui est désigné comme "zombie" dans le ps), alors c'est un inoffensif enregistrement dans la liste des processus en attente de quelqu'un pour recueillir son code de retour et il peut être ignoré en toute sécurité.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X