the CateIocompletionPort code >
fonction permet de créer un nouveau port d'achèvement d'E / S et l'enregistrement des poignées de fichier à un port d'achèvement d'E / S existant. P>
Ensuite, je peux utiliser n'importe quelle fonction, comme un Je dois vérifier si l'appel de la fonction renvoyé de manière synchrone, bien qu'il ait été appelé avec une structure code> superposé code> et dans ce cas, la poignée directement. Dans l'autre cas, lorsque La question qui se pose sont: p>
Comment puis-je supprimer une poignée du port d'achèvement d'E / S? Par exemple, lorsque j'ajoute des sockets à l'IOCP, comment puis-je supprimer des fermées? Devrais-je simplement ré-enregistrer une autre prise avec la même clé d'achèvement? P> LI>
En outre, est-il un moyen de rendre les appels toujours passer sur le port d'achèvement d'E / S et ne retournez pas de manière synchrone? P> LI>
et enfin, est-il possible par exemple de Que se passe-t-il si un RECV code> sur une prise ou un
listifile code> sur un fichier avec un
superposé code> Structure une opération asynchrone. P>
error_io_pending code> est renvoyé, je peux utiliser le
GetQueSueCompletionStatus code>
fonction à notifier lorsque l'opération est terminée. P>
RECV code> asynchrone mais à
envoyer code> de manière synchrone? Par exemple, lorsqu'un service d'écho simple est implémenté: puis-je attendre avec un
asynchrone
recv code> pour de nouvelles données mais
envoyer code> la réponse de manière synchrone afin que la complexité du code soit réduite? Dans mon cas, je ne serais pas
asynchrone code> a été demandé, mais avant de terminer, un
wrôlerfile code> dans le même fichier doit être traité. Est-ce que le
listerfile code> est-il annulé avec un message d'erreur et je dois redémarrer le processus de lecture dès que l'écriture est terminée? Ou dois-je annuler le
listerfile code> manuellement avant d'écrire? Cette question se pose en combinaison avec un dispositif de communication; Donc, l'écriture et la lecture ne doivent pas faire des problèmes si cela se passe simultanément. P> li>
ul>
4 Réponses :
Comment puis-je supprimer une poignée du port d'achèvement d'I / S? P> blockQuote>
Dans mon expérience, vous ne pouvez pas dissocier une poignée d'un port d'achèvement. Toutefois, vous pouvez désactiver la notification de port d'achèvement en définissant le bit à faible commande de votre
de la structure code> code> HEVENT code> de la structure: voir la documentation pour GetQueSueCompletionStatus . P>
Par exemple, lorsque j'ajoute des sockets à l'IOCP, comment puis-je supprimer les fermés? Devrais-je simplement ré-enregistrer une autre prise avec la même clé d'achèvement? P> blockQuote>
Il n'est pas nécessaire de dissocier explicitement une poignée d'un port d'achèvement d'E / S; la fermeture de la poignée est suffisante. Vous pouvez associer plusieurs poignées avec la même clé d'achèvement; La meilleure façon de déterminer quelle demande est associée à l'achèvement d'E / S consiste à utiliser la structure code> superposée code>. En fait, vous pouvez même étendre
chevauché Code>
pour stocker des données supplémentaires. P>Aussi, est-il un moyen de rendre les appels toujours sur le port d'achèvement d'E / S et ne retournez pas de manière synchrone? P> blockQuote>
C'est le comportement par défaut, même lorsque
listifile code> /
warserfile code> renvoie
true code>. Vous devez expliquer explicitement SetFilecompletimotificationModes pour dire Windows à Pas en faise un paquet d'achèvement lorsque
true code> et
error_success code> est retourné. p>
est-il possible par exemple de
recv code> asynchrone mais à
envoyer code> synchrone? p> blockQuote>
pas à l'aide de
RECV code> et
Envoyer code>; Vous devez utiliser des fonctions qui acceptent les structures code> superposées code>, telles que
wsaRecv code>
,wsasend code>
ou alternativementlistifile code>
etwrôlerfile code>
. Il peut être plus pratique d'utiliser ce dernier si votre code est destiné à travailler plusieurs types de poignées d'E / S, telles que les deux sockets et les tuyaux nommés. Ces fonctions fournissent un mode synchrone, donc si vous utilisez ceux-ci, vous pouvez mélanger des appels asynchrones et synchrones. P>Que se passe-t-il si un fichier de lecture asynchrone a été demandé, mais avant qu'il ne termine, un fichier d'écriture au même fichier doit être traité? P> blockQuote>
Il n'y a pas d'annulation implicite. Tant que vous utilisez des structures code> Séparez code> pour chaque lecture / écriture sur un périphérique en duplex intégral, je ne vois aucune raison pour que vous ne puissiez pas faire des opérations d'E / S simultanées. P>
"Cependant, vous pouvez désactiver la notification du port d'achèvement en définissant le bit à faible commande de votre champ Hentit de la structure superposée". Je n'ai pas pu désactiver la notification de port d'achèvement pour une prise donnée à l'aide de cette option. Mon cas: (1) Créez une prise, (2) Ajouter au port d'achèvement, (3) Appel WSARECV, (4) s'il renvoie WSA_IO_PENDING - OK, (5) si elle renvoie erros_success -> Je veux fermer immédiatement le socket et ne recevez pas de notification sur cette prise dans le port d'achèvement
d'abord quelques corrections importantes. P>
Dans le cas où l'opération d'E / S chevauchée complète immédiatement ( En outre, selon vos questions, je pense que vous confondez entre les poignées de fichier / prise et les opérations d'E / S spécifiques émises sur elles. P>
Maintenant, en ce qui concerne vos questions: p>
Une question plus correcte doit être la manière dont le fichier / socket doit être correctement fermé. La réponse est la suivante: ferme votre poignée. Toutes les opérations d'E / S en circulation (émises sur cette poignée) reviendront bientôt avec un code d'erreur (avortement). Ensuite, dans votre routine d'achèvement (celle qui appelle Comme je l'ai déjà dit, toute l'achèvement d'E / S arrive à IOCP dans des cas synchrones et asynchrones. La seule situation où il n'arrive pas à IOCP est quand un E / S complète de manière synchrone avec une erreur Vous devez utiliser Il n'y a pas de problème à mélanger des demandes de lecture / d'écriture recouvertes. Le seul point délicat est ce qui se passe ici si vous essayez de lire les données de la position de fichier où vous écrivez actuellement. Le résultat peut dépendre de choses subtiles, telles que l'ordre d'achèvement des E / S par le matériel, certains paramètres de chronométrage PC et etc. Une telle situation doit être évitée. P> li>
ol> listifile code> ou une fonction d'E / S similaire renvoie le succès) - L'achèvement d'E / S est déjà strong> prévu à l'IOCP . p>
getQueDeccleTionnstatus code> dans une boucle) devrait effectuer le nettoyage nécessaire par Per-I / O. P>
postquacéeCompletionStatus code>). P> li>
wsaSend code> et
wsaecv code> (pas
recv code> et
envoi code>) pour i / O. Néanmoins, même du socket a été ouvert avec le drapeau
wsa_flag_overlapped code> - vous êtes autorisé fort> d'appeler les fonctions d'E / S sans spécifier la structure code> superposée code>. Dans ce cas, ces fonctions fonctionnent de manière synchrone.
Afin que vous puissiez choisir des modes synchrones / asynchrones pour chaque appel de fonction. P> li>
Si une opération recouverte se termine immédiatement, WSARECV renvoie une valeur de zéro et le paramètre LPNumberOfByTesRecvd est mis à jour avec le nombre d'octets reçus et les bits d'indicateur indiqués par le paramètre LPFLAGS sont également mis à jour. Si l'opération recouverte est initiée et complétera plus tard, WsaRecv renvoie Socket_Error et indique le code d'erreur WSA_IO_PENDING. Code> Pourquoi mentionnent-ils le cas où l'opération réussit et se termine de manière synchrone alors s'il n'est pas possible de se produire?
Il est B> possible. C'est ce qui arrive parfois. De plus, pour le fichier E / S, c'est ce qui se passe habituellement (les E / SHO asynchrones sont rares dans des conditions normales).
Comment puis-je supprimer une poignée du port d'achèvement d'E / S? Par exemple, lorsque j'ajoute des sockets à l'IOCP, comment puis-je supprimer des fermées? Devrais-je simplement ré-enregistrer une autre prise avec la même clé d'achèvement? P> blockQuote>
Vous avez le mauvais chemin autour. Vous définissez le port d'achèvement d'E / S à utiliser par un objet de fichier - lorsque l'objet de fichier est supprimé, vous n'avez rien à craindre. La raison pour laquelle vous êtes confus est à cause de la façon dont Win32 expose la fonctionnalité API native sous-jante (
CreateIocompletionPort code> fait deux choses très différentes en une seule fonction). P>
aussi, y a-t-il un moyen de faire les appels Toujours aller sur le port d'achèvement des E / S et ne revenez pas de manière synchrone? P> blockQuote>
Voici comment ça a toujours été. En commençant par Windows Vista, pouvez-vous personnaliser la manière dont les notifications d'achèvement sont traitées. P>
Que se passe-t-il si une asynchrone Listerfile a été demandé, mais Avant de compléter, un wrtorfile à Le même fichier doit être traité. Le fichier Lecture sera-t-il annulé avec un Message d'erreur et je dois redémarrer le processus de lecture dès que l'écriture est complet? p> blockQuote>
Les opérations d'E / S sous Windows sont asynchrones de manière inhérale et les demandes sont toujours en file d'attente. Vous ne pouvez pas penser que ceci est donc parce que vous devez spécifier
file_flag_overlapcid code> dans
créeefile code> pour activer les E / S asynchrones. Cependant, à la couche indigène, les E / S synchrones sont vraiment un complément, une chose de commodité où le noyau conserve la piste de la position du fichier et attend que les E / S complètent avant de retourner. P>
Comme je l'ai déjà signalé là , la croyance généralement tenue qu'il est impossible de supprimer les poignées des ports d'achèvement, c'est faux , probablement causé par l'abscence de tout indice quant à la façon de le faire de presque toutes les documents que je pouvais trouver. En fait, c'est assez facile: p>
appeler NTSETTINformationFile code>
avec le filereplacecompletionInformation code> Enumerator Valeur pour
FileInformationClass Code> et un pointeur sur un
file_completion_information code>
structure pour le FileInformation < / code> paramètre. Dans cette structure, définissez le membre
port code> sur
null code> (ou
nullptr code>, en C ++) pour dissocier le fichier du port, il est actuellement attaché à ( Je suppose que si ce n'est pas attaché à aucun port, rien ne se passerait),
ou définir
port code> sur une poignée code> valide code> à un autre port d'achèvement pour associer le fichier avec celui-ci à la place. P>
Remarque: Si vous suivez le lien vers les documents file_combletion_information, vous verrez "Cette structure est disponible à partir de Windows 8.1."
Mais est-ce disponible dans l'espace utilisateur?