2017-09-24 2 views
0

J'implémente un éditeur de texte Win32 Console qui a une file d'attente interne pour transmettre des informations sur les zones à redessiner, les messages de/vers les plugins, etc. Je préfère qu'il soit mono-threadé par défaut (s'il ne se passe rien cela nécessite des threads supplémentaires). J'envisage 2 stratégies de message de mise en œuvre de la file d'attente:Est-il acceptable pour un éditeur de texte de transmettre chaque touche d'un thread à un autre?

  1. Utiliser la file d'usage général et Win32 événement, donc je peux utiliser WaitForMultipleObjectsEx attendre pour les messages internes et l'entrée d'utilisateur en même temps, passant à la fois la poignée d'entrée de la console et la poignée de l'événement. Dans ce cas, l'éditeur de texte peut vivre entièrement dans un seul thread.
  2. Utiliser le port d'achèvement d'E/S. Dans ce cas, l'éditeur de texte aura besoin d'au moins deux threads, l'un appelant GetQueuedCompletionStatus pour recevoir des messages, et un autre lisant l'entrée de l'utilisateur et l'envoyant en file d'attente via PostQueuedCompletionStatus. La raison pour laquelle le handle d'entrée de la console ne peut pas se chevaucher et les fonctions WaitFor* n'acceptent pas le port d'achèvement comme un handle attendu, il n'est donc pas possible de les attendre simultanément. Tout comme dans la première configuration, les deux threads ne perdent pas de temps CPU lorsqu'il n'y a pas d'entrées ou d'événements, mais chaque pression de touche doit être transmise d'un thread à l'autre via IOCP.

Quelle est la meilleure conception?

L'inconvénient de performance et de latence est-il dû au passage de chaque pression de touche via IOCP significatif pour un éditeur de texte?

+0

Je ne connais pas Windows, mais vous avez très peu de touches toutes les secondes. Les ordinateurs sont rapides. –

+0

Même si les threads n'attendent que le mode kernel, vous perdez encore de la mémoire si vous avez des threads inutiles. – Anders

+0

Avez-vous envisagé d'utiliser une boîte à outils multiplateforme comme [Qt] (http://qt.io)? Ensuite, vous ferez ce que cette boîte à outils fournit –

Répondre

2

La performance et la latence de l'IOCP conviennent à votre utilisation. Je ne traduirais cependant pas chaque pression de touche sur PostQueuedCompletionStatus. Je préférerais PostQueuedCompletionStatus pour mettre en file d'attente plusieurs claviers à la fois, quel que soit le nombre de ReadConsoleInput.

Je pense que la différence de performance est minime, l'une ou l'autre peut être plus rapide en fonction de l'environnement. Et WaitForMultipleObjects est beaucoup plus facile à implémenter.

P.S. Vous êtes sûr que vous avez besoin d'une file d'attente de messages? Pourquoi ne traitez-vous pas ces requêtes de redessin/messages de plugin dans le thread qui a déclenché ceux-ci, en utilisant par ex. section critique à surveiller (sortie console + votre état partagé)? Si votre encombrement est faible, comme les messages 100Hz + 15Hz et que vous les traitez rapidement, vous aurez une latence encore plus faible que celle d'IOCP ou de n'importe quelle autre file d'attente: avec une congestion faible ou un verrouillage bref, les sections critiques noyau pour le verrouillage/déverrouillage. Cela simplifiera également la conception, votre thread principal dormira en bloquant l'appel ReadConsoleInput(), pas besoin de WaitFor .. avant cela.

+0

Merci pour votre réponse! Je considérerai la messagerie synchrone que vous avez suggérée, elle semble beaucoup mieux au moins pour certains types de messages. La raison d'avoir une file d'attente de messages + WaitFor * '/ GetQueuedCompletionStatus' est la possibilité de faire des E/S dans le thread principal via E/S ou IOCP, respectivement, tout ne doit pas être entièrement réentrant, ce qui est nécessaire (si ma compréhension est correcte) si tout est appelé sur place. – jhkouy78reu9wx

+0

@ jhkouy78reu9wx IOCP n'est que bien meilleur que les E/S avec alerte lorsque vous avez plusieurs demandes de complétion de traitement de threads ou que vous avez plus de MAXIMUM_WAIT_OBJECTS = 64 flux concurrents.Si vous n'avez pas beaucoup de flux, mon attente est WaitForMultipleObjects est tout aussi rapide que IOCP. L'entrée de la console de traitement dans la même file d'attente asynchrone peut être intéressante: l'utilisateur appuie sur les touches ~ 10Hz max, l'async IO peut compléter à 1 KHz ou plus, mais en latence. WaitForMultipleObjects est légèrement meilleur pour ça car il priorise les handles par ordre. – Soonts