Sous Linux, qu'advient-il de l'état d'un processus lorsqu'il doit lire des blocs à partir d'un disque? Est-ce bloqué? Si oui, comment un autre processus est-il choisi pour s'exécuter?
Réponses
Trop de publicités?Lorsqu'un processus a besoin d'extraire des données à partir d'un disque, elle s'arrête en cours d'exécution sur le PROCESSEUR de laisser à d'autres processus de s'exécuter car l'opération peut prendre beaucoup de temps - à moins de 5ms temps de recherche pour un disque qui est commun, et 5ms est de 10 millions d'UC cyles, une éternité, du point de vue de la programme de !
À partir du programmateur de point de vue (aussi dit "userspace"), ce qui est appelé un système de blocage d'appel. Si vous appelez write(2)
(ce qui est une fine libc wrapper autour de l'appel système du même nom), vous processus n'est pas exactement s'arrête à cette limite : il continue, sur le noyau côté, l'exécution de l'appel système de code. La plupart du temps, il va tout le chemin jusqu'à un disque spécifique controleur pilote (fichier -> système de fichiers/VFS -> appareil -> pilote de périphérique), où une commande pour récupérer un bloc sur le disque est soumis à du matériel adéquat : c'est une opération très rapide la plupart du temps.
PUIS le processus s'est mis en état de veille (dans l'espace noyau, le blocage est appelé dormir, rien n'est jamais "bloqué" à partir du noyau de point de vue). Il sera réveillé encore une fois que le matériel a enfin récupéré les données appropriées, alors le processus sera marqué comme praticable, planifié et exécuté en tant que bientôt en tant que planificateur permet de.
Enfin dans l'espace utilisateur, le système de blocage d'appel de retour avec un véritable statut et de données, et le déroulement du programme.
Il est possible d'invoquer la plupart des I/O appels système en mode sans blocage (voir O_NONBLOCK en open(2)
et fcntl(2)
). Dans ce cas, le système demande le retour immédiat et dit seulement à propos de la bonne présentation de l'opération de disque. Le programmeur devra explicitement vérifier à une date ultérieure, si l'opération s'est terminée, avec succès ou non, et extraire de son résultat (par exemple avec des select(2)
). Ceci est appelé asynchrone ou de l'événement en fonction de la programmation.
La plupart des réponses ici de mentionner le D de l'état (dont le nom exact est TASK_UNINTERRUPTIBLE de Linux sate noms) sont incorrects. Le D état est un spécial mode sommeil qui est déclenchée uniquement dans un espace noyau chemin de code, lorsque le chemin d'accès du code ne peut pas être interrompu (car il serait complexe à programmer), la plupart du temps dans l'espoir qu'il pourrait bloquer très peu de temps. Je crois que la plupart des "D états" sont invisibles, ils sont de très courte durée et ne peut pas être observé par l'échantillonnage des outils tels que 'top'.
Mais vous rencontrerez parfois des personnes peut être tué processus D état dans quelques situations. NFS est célèbre pour ça, j'ai rencontré à de nombreuses reprises. Je pense qu'il y a une sémantique de l'affrontement entre certains VFS chemins de code qui supposent toujours des disques locaux et rapide de détection d'erreur (sur SATA, une erreur de délai d'attente seraient de l'ordre de quelques 100 ms), et NFS qui, de fait, récupère des données à partir du réseau qui est plus résistant et a la récupération lente (un timeout TCP de 300 secondes). Lire [1] pour les frais de solution introduit dans Linux 2.6.25 avec le TASK_KILLABLE état. Avant cette époque, il y avait un hack où l'on pouvait envoyer des signaux à NFS processus clients par l'envoi d'un signal SIGKILL à le thread du noyau rpciod, mais oublier ce vilain truc...
En attendant read()
ou write()
vers/à partir d'un fichier descripteur de retour, le processus sera mis dans un type particulier de sommeil, connu comme le "D" ou "la Veille du Disque". C'est spécial, parce que le processus ne peuvent pas être tués ou interrompu alors que dans un tel état. Un processus en attente d'un retour de ioctl() serait également mis à la veille de cette manière.
Une exception à cette règle est lorsqu'un fichier (tel qu'un terminal ou un autre caractère de l'appareil) est ouvert en O_NONBLOCK
mode, adopté lors de son supposé que un périphérique (tel qu'un modem) auront besoin de temps pour s'initialiser. Toutefois, vous avez indiqué les périphériques de bloc dans votre question. Aussi, je n'ai jamais essayé un ioctl()
qui est susceptible de bloquer sur un fd ouvert en non mode de blocage (au moins pas consciemment).
Comment un autre processus est choisi dépend entièrement du planificateur, vous utilisez, ainsi que les autres processus pourrait avez fait pour modifier leur poids au sein de cette planificateur.
Certains programmes de l'espace utilisateur, dans certaines circonstances, ont été connus pour rester dans cet état pour toujours, jusqu'à ce que redémarré. Ce sont généralement groupés avec d'autres "zombies", mais le terme ne serait pas correct car ils ne sont pas techniquement obsolète.
L'état d'un processus de l'exécution OI sera mise en D état(interrompu le sommeil), ce qui libère le CPU jusqu'à ce qu'il y a une interruption matérielle qui indique au PROCESSEUR pour revenir à l'exécution du programme. Vous pouvez homme ps pour voir les autres états de processus.
En fonction de votre noyau, il y a un process scheduler qui conserve la trace d'une runqueue de processus prêts à s'exécuter. Ce avec un algorithme d'ordonnancement indique au noyau de processus pour l'attribuer à qui de la CPU. Il y a aussi le noyau des processus et des processus utilisateur à prendre en compte. Et chaque processus se voit attribuer une tranche de temps, ce qui est un morceau de temps CPU qu'il est autorisé à utiliser. Une fois que le processus utilise la totalité de sa tranche de temps, il est marqué comme étant arrivé à expiration et une priorité moindre dans l'algorithme d'ordonnancement.
Dans le cas du noyau 2.6, il est un O(1) la complexité du planificateur, donc, peu importe la façon dont de nombreux procédés, vous avez jusqu'en marche, il va assigner des Cpu en temps constant. C'est plus compliqué, mais, depuis 2.6 introduit la préemption et le CPU load balancing ce n'est pas une simple algorithme. Dans tous les cas, l'efficacité et la Cpu ne sera pas rester les bras croisés pendant que vous attendez pour IO. Espérons que ça aide!
Oui, la tâche est bloquée dans l'appel système read (). Une autre tâche qui est prêt fonctionne, ou si pas d'autres tâches sont prêts, la tâche d'inactivité (pour la CPU) s'exécute.
Normal, le blocage de la lecture du disque provoque la tâche pour entrer dans le "D" de l'état (comme d'autres l'ont noté). Ces tâches contribuent à la moyenne de chargement, même s'ils ne sont pas la consommation de la CPU.
Certains autres types de IO, surtout ats et réseau, ne se comportent pas tout à fait le même - le processus se termine par un "S" de l'état et peut être interrompu et ne comptent pas dans la moyenne de charge.
En supposant que votre processus est un seul fil, et que vous êtes à l'aide de blocage I/O, votre processus de bloc d'attente pour les I/O pour valider. Le noyau va chercher un autre processus à exécuter dans l'intervalle basé sur la gentillesse, la priorité, la dernière moment de l'exécution, etc. Si il n'y a pas d'autres processus exécutables, le noyau ne fonctionnent pas; au lieu de cela, il va dire le matériel, la machine est à l'arrêt (ce qui entraînera une réduction de la consommation d'énergie).
Les processus qui sont en attente d'e/S se termine généralement dans l'état D, par exemple, ps
et top
.