Comment faire pour voir si un tube est vide
En supposant une pipe,
int pipe_fd[2];
pipe(pipe_fd);
Nous fourche, et s'attendre à ce que l'un processus d'écriture dans le tube à un moment arbitraire. Dans l'un des processus, nous voulons être en mesure de vérifier le contenu de la pipe sans blocage.
c'est à dire Tandis qu'une lecture de bloc si rien n'est présent et à l'écriture, à la fin reste ouverte. Je veux aller faire d'autres choses et peut-être même de lire un peu à la fois, faire quelques trucs, puis vérifier à nouveau pour voir si il n'y a plus, à la:
close(pipe_fd[1]);
while(1){
if(/**Check pipe contents**/){
int present_chars = 0;
while( read(pipe_fd[0],&buffer[present_chars],1) != 0)
++present_chars;
//do something
}
else
//do something else
}
Depuis le
Notez que Linux a aussi le
pipe()
fonction ne vous permet pas de jeu non-blocage de la mode, vous avez à faire après la pipe est créé avec fcntl()
et F_GETFL
et F_SETFL
plus O_NONBLOCK
.Notez que Linux a aussi le
pipe2
fonction, ce qui vous permet de demander la non bloquante en mode dans le même temps, le tube est créé. Cette fonction n'est pas encore la norme, mais il a été accepté d'inclure dans la prochaine version de POSIX depuis il est également nécessaire pour atomiquement réglage du close-on-exec drapeau dans le même temps, le tube est créé.OriginalL'auteur darkpbj | 2012-12-11
Vous devez vous connecter pour publier un commentaire.
Votre logique est mal dans cette
read
ne sera pas de retour à 0 lorsqu'il est à court de caractères; au lieu de cela, il permet de bloquer jusqu'à ce qu'il reçoit de plus, sauf si vous mettez le fichier en mode sans blocage, mais ensuite, il renvoie -1 et définirerrno
àEWOULDBLOCK
ouEAGAIN
plutôt que de retourner 0. La seule foisread
peut jamais de retour est 0 quand la taille de l'argument est 0 ou de fin de fichier a été atteinte. Et, pour les tuyaux, fin-de-fichier de l'écriture à la fin de la canalisation a été fermé; fin-de-fichier d'état ne se produit pas tout simplement parce que il n'y a pas une entrée encore disponible.Avec cela dit, la façon la plus simple de vérifier est:
mais à moins que vous êtes en utilisant un mode non bloquant, vous aurez besoin de faire cette vérification avant chaque opération de lecture. Passant une grande mémoire tampon de
read
plutôt que de le faire un byte-à-un-temps permettrait d'éliminer la plupart des coûts de la vérification.read(3)
, "Si [...]O_NONBLOCK
est définie,read()
[ ... ] errno contient[EAGAIN]
,", pasEWOULDBLOCK
. Eh bien, sauf si nous sommes à l'aide de différentes implémentations.La valeur "correct" est
EWOULDBLOCK
. Moderne POSIX permet soit, et permet à la fois d'erreur macros avoir la même valeur, ce qui n'sur Linux. Voir pubs.opengroup.org/onlinepubs/9699919799/functions/read.html à proprement parler, une application portable doit testererrno==EAGAIN || errno==EWOULDBLOCK
.Oh bien. Je n'étais pas au courant. Pourtant, c'est écrit dans mon manfile trop... Merci 🙂
Mise à jour de ma réponse au point qu'il pourrait être.
Et de même sur la vôtre, car vous réellement couverte comment utiliser le mode non bloquant.
OriginalL'auteur R..
Vous pouvez vérifier si il y a des données à lire avec la
read()
fonction. Deread(3)
:Donc, si vous définissez
O_NONBLOCK
, vous serez en mesure de dire si quelque chose est à lire sur le tuyau, en appelant simplementread()
.Comme un rappel, à partir de
open(3)
:J'espère que cela aide.
OriginalL'auteur 7heo.tk
R..'s réponse est bonne cependant sondage retourne le nombre de descripteurs de fichiers les structures qui ont des indicateurs spécifiés dans "revents". Ce sera 1 si vous pouvez lire à partir de
fd
mais sera également 1 si l'un des indicateurs d'erreur sont définis. Cela signifie R..'s réponse va dire que la pipe est lisible si jamais il entre dans un état d'erreur. Un plus robuste de contrôle pourrait être quelque chose comme ceci:OriginalL'auteur hippiemancam