Il existe en fait trois gradations dans les appels système.
- Certains appels système reviennent immédiatement. «Immédiatement» signifie que la seule chose dont ils ont besoin est un peu de temps processeur. Il n'y a pas de limite stricte au temps qu'ils peuvent prendre (sauf dans les systèmes en temps réel ), mais ces appels reviennent dès qu'ils sont planifiés depuis assez longtemps.
Ces appels sont généralement appelés non bloquants . Des exemples d'appels non bloquants sont des appels qui lisent juste un peu de l' état du système, ou faire un simple changement d'état du système, tels que getpid
, gettimeofday
, getuid
ou setuid
. Certains appels système peuvent être bloquants ou non bloquants selon les circonstances; par exemple, read
ne bloque jamais si le fichier est un canal ou un autre type qui prend en charge les lectures non bloquantes et si l' O_NONBLOCK
indicateur est défini.
- Quelques appels système peuvent prendre un certain temps, mais pas pour toujours. Un exemple typique est
sleep
.
- Certains appels système ne reviendront pas jusqu'à ce qu'un événement externe se produise. Ces appels seraient bloquants . Par exemple,
read
appelé sur un descripteur de fichier bloquant est bloquant, et il en est de même wait
.
La distinction entre les appels système «rapides» et «lents» est proche du non-blocage et du blocage, mais cette fois du point de vue de l'implémenteur du noyau. Un appel système rapide est un système connu pour pouvoir être exécuté sans blocage ni attente. Lorsque le noyau rencontre un appel système rapide, il sait qu'il peut exécuter l'appel système immédiatement et garder le même processus planifié. (Dans certains systèmes d'exploitation avec multitâche non préemptif , les appels système rapides peuvent être non préemptifs; ce n'est pas le cas dans les systèmes Unix normaux.) En revanche, un appel système lent nécessite potentiellement d'attendre la fin d'une autre tâche, de sorte que le noyau doit se préparer à suspendre le processus d'appel et à exécuter une autre tâche.
Certains cas sont un peu une zone grise. Par exemple, une lecture de disque (à read
partir d'un fichier normal) est normalement considérée comme non bloquante, car elle n'attend pas un autre processus; il n'attend que le disque, ce qui prend normalement un peu de temps pour répondre, mais ne prendra pas éternellement (c'est donc le cas 2 ci-dessus). Mais du point de vue du noyau, le processus doit attendre la fin du pilote de disque, c'est donc définitivement un appel système lent.
Gilles 'SO- arrête d'être méchant'
la source
O_NONBLOCK
drapeau. Si l'indicateur est défini, l'appel système peut se terminer sans attendre quoi que ce soit d'autre, il n'est donc pas bloquant et le noyau peut le traiter comme un appel système rapide.Un appel système lent est quelque chose comme un socket TCP read () - si vous n'avez pas O_ASYNC (ou autre) défini, il peut attendre indéfiniment.
Un appel système rapide est quelque chose comme gettimeofday () ou getpid (), qui renvoient tous deux au processus que le noyau a immédiatement disponible.
Les lectures sur disque entrent dans la catégorie des appels système lents. Si un processus effectue une lecture () sur un vrai fichier disque, descripteur de fichier, le noyau peut avoir à lire dans un ou plusieurs blocs de disque pour satisfaire la lecture. Selon la structure sur disque du système de fichiers sous-jacent, cela peut signifier la lecture de l'inode sur disque pour obtenir le numéro de bloc de disque d'un "bloc indirect", la lecture du bloc indirect pour obtenir le bloc de données, puis la lecture du bloc de données lui-même . Beaucoup de temps, au moins en termes de cycles CPU par accès disque, probablement pire aujourd'hui qu'il ne l'était au bon vieux temps.
Je ne l'ai pas vu depuis des lustres, mais la "moitié inférieure" de l'ancien code de pilote de périphérique de lecteur de disque Unix bloquerait les signaux / interruptions afin qu'il soit plus facile de maintenir l'intégrité du système de fichiers sur le disque. Parfois, un pilote buggé ou un disque défaillant ne remettrait jamais le bloc de disque qu'un processus avait demandé, et le processus dormait pour toujours. Même un kill -9 n'y a rien fait.
la source