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).