2010-08-26 31 views
4

Je dois exécuter du code dans le contexte du thread principal. J'utilise Lazarus + FPC. Je reçois un événement d'un thread à l'intérieur d'une DLL (bibliothèque partagée si sous Linux) et ma fonction de rappel est appelée. Notez que cette fonction n'est membre d'aucune classe mais une fonction traditionnelle autonome avec une directive "cdecl" attachée.Exécuter du code dans le contexte du thread principal (Lazarus)

Je dois trier un gestionnaire d'événements de propriétés correspondant à chaque message que je reçois. Et ces événements doivent être transmis dans le contexte du fil principal. Je connais deux de ces solutions:

  1. PostMessage
  2. Application.QueueAsyncCall

Le premier est ok, mais il faut une poignée de fenêtre. Et comme il s'agit d'un code de bibliothèque, aucune poignée n'est disponible. AllocateHWND n'est pas une option car il n'est pas multi-plateforme. Je sais que je peux créer une forme fictive mais c'est une très mauvaise solution

La seconde fonctionne bien, mais j'ai un problème, que l'appel n'est pas traité jusqu'à ce que je déplace une souris dans l'application par exemple. Peut-être que je fais quelque chose de mal, je ne sais pas. C'est comme si mon appel était en cours de traitement seulement quand le traitement des messages intervient. Mais cela peut être une longue attente apparemment.

Donc, je veux savoir quelle est la meilleure solution ici (probablement QueueAsyncCall) et comment je peux être sûr que mon message (appel) sera traité dans des délais acceptables?

Répondre

1

Vous ne pouvez pas être sûr à 100%, comme vous ne pouvez le faire dans aucun système non temps réel. Si le thread principal se bloque, il ne vérifie pas les messages ou autres événements dans la boucle principale. C'est normal. La seule chose que vous pouvez faire est d'éviter de faire des choses dans le thread principal qui peut prendre beaucoup de temps. C'est le tour du métier de juger exactement ce qui est nécessaire et ce qui ne l'est pas. Certaines personnes orientées temps réel déplacent tous les accès au système de fichiers vers des threads, et gardent l'interface graphique strictement pour l'interface utilisateur, simplement parce que si un utilisateur configure un chemin sur un partage réseau pour ceci ou pour l'autre, un problème avec le partage peut facilement de minutes même.

Si je regarde application.queueasynccall, je ne vois pas de traitement threadsafe (pas de files d'attente verrouillées ou verrouillées), de sorte que l'on est sorti. Je sais que postmessage est émulé par Lazarus dans une certaine mesure sur Windows, et j'ai vérifié l'implémentation et il a un verrou, donc je suppose qu'il est multithread sûr.

+0

Je suis bien conscient que je ne peux pas être sûr à 100%, mais mon application ne fait rien et toujours les appels ne sont pas traités jusqu'à ce que je bouge la souris. Donc, je suis mieux avec PostMessage. Mais l'inconvénient est que AllocateHWND n'est pas encore implémenté en mode crossplatform. Ou est-ce? Je pensais que Application.QueueAsyncCall était threadsafe. Je vais vérifier la mise en œuvre. Merci pour la réponse si. J'ai beaucoup d'expérience dans l'environnement multithread mais je suis assez nouveau à Lazarus. Ainsi les problèmes :) – Runner

+0

L'horreur :) Il est vraiment pas threadsafe. Donc, existe-t-il une alternative à la messagerie en dehors de PostMessage? Je veux dire simple, pas IPC ou TCP/IP? – Runner

+0

Pas vraiment. Je suppose qu'ils ont eu la peine de mettre en place une émulation post-message sur d'autres plateformes pour une raison. –