91 votes

UNIX I/O non bloquant : O_NONBLOCK vs FIONBIO

Dans chaque exemple et discussion-je courir à travers dans le contexte de la programmation socket BSD, il semble que la méthode recommandée pour définir un descripteur de fichier pour non bloquantes I/O mode est à l'aide de l'indicateur de la fcntl(), par exemple

int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);

J'ai été faire de la programmation réseau sous UNIX depuis plus de dix ans, et ont toujours utilisé l' FIONBIO ioctl() appel pour ce faire:

int opt = 1;
ioctl(fd, FIONBIO, &opt);

Jamais vraiment donné beaucoup de pensée à la raison. Juste appris de cette façon.

Quelqu'un aurait-il un quelconque commentaire sur la possible mérites respectifs de l'un ou de l'autre? J'imagine que la portabilité locus varie un peu, mais ne savez pas à quel point en tant que ioctl_list(2) ne parle pas de l'aspect de la personne ioctl méthodes.

131voto

mark4o Points 20472

Avant la normalisation, il a été ioctl(...FIONBIO...) et fcntl(...O_NDELAY...), mais ils se sont comportés de façon incohérente entre les systèmes, et même au sein du même système. Par exemple, il était commun pour FIONBIO de travail sur les prises et O_NDELAY de travail sur les téléscripteurs, avec beaucoup d'incohérence pour des choses comme des tuyaux, fifo, et les périphériques. Et si vous ne savez pas quel type de descripteur de fichier que vous avez eu, vous auriez à régler à la fois pour être sûr. Mais, en outre, un non-bloquant lire avec pas de données disponibles a également été indiqué de façon incohérente; selon le système d'exploitation et le type de descripteur de fichier, la lecture peut retourner 0, ou -1 avec errno EAGAIN, ou -1 avec errno EWOULDBLOCK. Même aujourd'hui, l'implantation FIONBIO ou O_NDELAY sur Solaris provoque une lecture avec pas de données permettant de retourner la valeur 0 sur un ats ou un tuyau, ou -1 avec errno EAGAIN sur un socket. Cependant 0 est ambiguë, car il est également retourné pour les expressions du FOLKLORE.

POSIX abordé ce avec l'introduction de l' O_NONBLOCK, qui a normalisé comportement à travers les différents systèmes et types de descripteur de fichier. Parce que les systèmes existants voulez généralement à éviter tout changement de comportement qui pourrait casser la compatibilité ascendante, POSIX a défini un nouveau drapeau, plutôt que de rendre obligatoire le comportement spécifique de l'un des autres. Certains systèmes comme Linux traiter tous les 3 la même, et aussi définir EAGAIN et EWOULDBLOCK à la même valeur, mais des systèmes qui souhaitent conserver une certaine autre comportement hérité pour la compatibilité descendante pouvez le faire lorsque les plus âgés sont les mécanismes utilisés.

Les nouveaux programmes devraient utiliser fcntl(...O_NONBLOCK...), normalisé par la norme POSIX.

6voto

EdH Points 630

Je crois que fnctl() est une fonction POSIX. Où en tant que ioctl() est une chose UNIX standard. Voici une liste de POSIX io . ioctl() est une chose très spécifique au noyau / pilote / système d'exploitation, mais je suis sûr que ce que vous utilisez fonctionne sur la plupart des versions d'Unix. certaines autres choses ioctl() pourraient ne fonctionner que sur certains OS ou même sur certains tours de son noyau.

5voto

Jonathan Leffler Points 299946

@Sean dit, fcntl() est largement standardisées, et donc disponible sur toutes les plateformes. L' ioctl() fonction précède fcntl() sous Unix, mais n'est pas standardisée. Que l' ioctl() a travaillé pour vous à travers toutes les plates-formes de pertinence pour vous, c'est de la chance, mais pas garanti. En particulier, les noms utilisés pour la deuxième argument sont des arcanes et ne sont pas fiables à travers les plates-formes. En effet, ils sont souvent uniques à particulier pilote de périphérique que le descripteur de fichier de références. ( ioctl() Des appels utilisé pour un bitmap graphics device en cours d'exécution sur un ICL Perq de course PNX (Perq Unix) d'il y a vingt ans ne traduit rien d'autre n'importe où d'autre, par exemple.)

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