2010-06-05 6 views
1

J'ai besoin de créer un assemblage mixte C++/CLI qui peut planifier les prochains appels dans une DLL native avec une précision d'une milliseconde.Planification en milliseconde-précision des événements futurs en C++/CLI

Cela signifiera, bien sûr, le réglage d'une minuterie (de quel type?) pendant une milliseconde ou trois à l'avance, puis tourner jusqu'à l'instant et appeler la fonction native DLL. En fonction de ce que j'ai lu, je suppose que le rappel que les appels de minuterie devront être natif pour s'assurer qu'il n'y a pas de thunks ou GC pour retarder le traitement du rappel de minuterie.

Est-ce que le thread ou le processus entier doit être natif et sans CLR, ou peut-il être fait aussi précisément aveC#pragma non géré ou en configurant un fichier de l'assembly à compiler comme natif?

Si oui, comment?

S'il n'y a en effet aucun moyen de le faire en mode mixte C++/CLI, quelle serait la meilleure façon de configurer un app/thread (ie, DLL ou exe?) Pour le gérer et obtenir les données aller-retour entre les threads/applications natifs et gérés?

+0

Il existe des structures, des unions, des chaînes de pascal, des tampons de longueur arbitraire, et de passer à la DLL native propriétaire, donc une réorganisation dans les types de données saner doit être effectuée en dehors des sections critiques en C++/CLI ou C++ natif avant d'essayer d'utiliser l'API de martialling .NET. –

+0

Je souhaite qu'il me laisse également ajouter "windows" et "callback" comme étiquettes. (Autres suggestions?) –

+1

Vous savez que sur un système d'exploitation multitâche préemptif, vous n'avez aucune garantie que votre code ne sera pas interrompu avant que le rappel ne se déclenche, que le thread exécute du code natif ou géré. –

Répondre

3

L'intégralité du fil doit être sans CLR. Dès qu'un code managé s'exécute sur le thread, il sera ajouté à la liste des threads du CLR à suspendre pendant la collecte. Votre dernière question, cependant, suggère que vous n'avez aucune idée sur le multithreading. Il n'y a pas de correspondance entre les threads et les DLL. Une DLL peut avoir plusieurs threads, et chaque thread peut exécuter du code à partir de nombreuses DLL (en fait, le fait toujours, si vous comptez les DLL Windows). Vous n'utilisez pas non plus l'expression "section critique" de la manière habituelle. Un assembly C++/CLI en mode mixte peut contenir un thread natif uniquement (démarrez-le en utilisant l'appel CreateThread natif, en passant une procédure thread native et n'appelez aucun code managé directement ou indirectement à partir de ce thread). Votre vie sera un peu plus facile si vous écrivez le code du thread natif dans un ou plusieurs fichiers à compiler sans/clr, ne pas avoir de code managé visible facilite l'évitement, mais méfiez-vous des pointeurs de fonctions qui peuvent être encapsulés délégués gérés. Au-delà, utilisez une synchronisation sans verrouillage, par ex. SList, ou votre thread natif pourrait finir par attendre un verrou maintenu sur un thread en mode mixte qui a été suspendu pour la récupération de place. Entre autres choses, cela signifie ne pas utiliser l'un des allocateurs partagés standard, car ils utilisent le verrouillage interne. Certains allocateurs sans verrous existent cependant.

EDIT: Les pointeurs de fonction qui enveloppent les délégués gérés sont créés en appelant Marshal::GetDelegateForFunctionPointer. Après cela, ils agissent comme des pointeurs vers des fonctions natives (il est possible de les différencier) et l'utilisation de l'opérateur d'appel de fonction sur un tel pointeur provoquera l'exécution du code managé sur le thread sensible.Dans la plupart des cas, cela ne posera pas de problème, assurez-vous simplement que si vous utilisez des délégués comme raccourci pour produire des rappels au code managé, faites-le à partir du thread mixte et non de celui que vous souhaitez utiliser uniquement en natif.

En général, vous voudrez probablement un type de schéma de transmission de message purement natif pour échanger des données. Le thread mixte peut rendre tous les appels natifs nécessaires, vous pouvez mélanger le code natif et le code managé sur tous vos autres threads, gardez juste le natif-natif.

Tout le thunking doit se produire sur le thread mixte, et il ne retardera pas le thread natif sensible au temps à moins que le thread mixte ne possède un verrou dont le thread natif a besoin. D'où ma suggestion d'utiliser un échange de données sans verrouillage.

+0

Donc, on peut faire un thread sans CLR dans un assemblage mixte, et ce thread peut être désinhibé par les threads gérés/mixtes? (Chercher d'autres personnes pour être d'accord ou pas d'accord, et pour expliquer plus loin.) Y a-t-il des "pointeurs de fonction enveloppant automatiquement les délégués gérés"? Comment puis-je éviter de les utiliser de manière accidentielle? Je suis conscient que les DLL mappent en tant que partie du chargeur et que les threads peuvent utiliser le code de nombreuses DLL. La question est la meilleure pratique: Que ce soit pour faire un processus pour cela (et, si oui, quelle est la meilleure façon d'y accéder) ou pour créer un thread natif (et comment coder les appels). –

+0

Je suis inquiet sur la façon d'interopérer dans le thread ou IPC dans le processus sans thunking pendant le moment sensible au temps. (Toutes mes excuses pour avoir appelé cette section critique quand je n'ai pas voulu dire verrouillage de contention.) –

0

Il ne peut pas être fait dans les fenêtres du tout - désolé. Obtenez un système d'exploitation qui correspond à vos besoins.

  • Les temporisateurs normaux dans les fenêtres ont une précision de 10ms.
  • Même si vous l'utilisez avec des minuteurs de haute performance, il n'y a aucune garantie de précision dans Windows que l'appel sera honoré dans un délai donné - votre appel 1ms peut arriver avec 5ms de retard.

Ce dont vous avez besoin/dont vous avez besoin, c'est d'un système d'exploitation en temps réel.

+0

Ce matériel n'a que des pilotes pour Windows. En Windows native, vous pouvez obtenir une fiabilité de 99,99% (supérieure à celle dont j'ai besoin) avec une précision de 1 ms. Il y a des exemples partout. J'en ai couru un et j'ai eu zéro échecs pendant que j'utilisais l'ordinateur toute la journée. LA QUESTION EST DE COMMENT APPORTER QUE .NET. SANS LAISSER. NET OBTENIR DANS LA VOIE DE LA SECTION CRITIQUE. Je veux savoir comment écrire le callback de sorte qu'aucune thunks ou GC ne se produise entre le timer qui se déclenche et le DLL qui est appelé. –

+0

Toujours pas de chance. Pour le GC - définir le GC non bloquant. En plus, il n'y a rien d'autre que je sache .NET met en travers de votre chemin. – TomTom