6
votes

Communication inter-thread. Comment envoyer un signal à un autre fil

dans mon application, j'ai deux threads

  1. Un "fil principal" qui est occupé la plupart du temps
  2. Un "thread supplémentaire" qui envoie une requête HTTP et qui bloque jusqu'à ce qu'il reçoive une réponse.

    Toutefois, la réponse HTTP ne peut être traitée que par le fil principal, car elle s'appuie sur son stockage à thread-local et sur des fonctions non threadsafe.

    Je cherche un moyen de dire le fil principal lorsqu'une réponse HTTP a été reçue et les données correspondantes. Le thread principal doit être interrompu par le thread supplémentaire et traiter la réponse HTTP dans les meilleurs délais, puis continuer à fonctionner du point où il a été interrompu avant.

    • Une façon dont je peux penser, c'est que le fil supplémentaire suspend le fil principal à l'aide de Suspendthread , copie les TLS du fil principal en utilisant un assembleur en ligne, exécute la fonction de traitement de réponse elle-même. et reprend le fil principal après.

    • Une autre solution dans mes pensées est, définissant un point de rupture sur une adresse spécifique dans la deuxième routine de rappel de threads, de sorte que le fil principal soit notifié lorsque le pointeur de l'instruction de deuxième threads marche sur ce point de rupture - et donc - a reçu la réponse HTTP.

      Cependant, les deux méthodes ne semblent pas bien être joliment, elles font mal, même si cela ne fait que penser à eux, et ils n'ont pas l'air vraiment fiable.

      Que puis-je utiliser pour interrompre mon fil principal , en disant qu'il devrait être poli et traiter la réponse HTTP avant de faire autre chose? Les réponses sans dépendances sur les bibliothèques sont appréciées, mais je prendrais également une certaine dépendance, si elle fournit une belle solution.

      suivant Question (En ce qui concerne la solution queueUserAPCC) a été répondu et expliqua qu'il n'existe aucune méthode sûre pour avoir un pousser -behaviour dans mon cas.


3 commentaires

Avez-vous vraiment besoin de "interrompre" votre fil principal? Comment fonctionne-t-il des travaux de traitement de toute façon, d'une file d'attente ou d'un autre mécanisme de travail?


Oui, l'interruption est ce que je veux accomplir dans mon cas (dans certains "push" -style. Pas de type attendre ou lookiffileSomettion ou sondage "Tirez" -style chose). La partie de traitement prend la réponse HTTP qui a été reçue du deuxième thread et appelle certaines fonctions non threadsafe à un interprète LUA après. Le "comment" pour obtenir le message du deuxième thread au thread principal pourrait être une mémoire partagée, mais cela n'a pas encore été corrigé car je ne sais pas comment laisser le deuxième fil notifier le fil principal de traiter maintenant .


Quel est votre fil principal? Est-ce interruptible?


7 Réponses :



1
votes

Je ne comprendrais peut-être pas la question, mais CreateSemaphore et < Un href = "http://msdn.microsoft.com/en-us/library/ms687032.aspx" rel = "Nofollow NOREFERRER"> WaitforsingleObject devrait fonctionner. Si un thread attend le sémaphore, il reprendra lorsque l'autre fil le signale.

Mise à jour basée sur le commentaire: Le thread principal peut appeler WaitforSingleObject avec un temps d'attente de zéro. Dans cette situation, il reprendra immédiatement si le sémaphore n'est pas signalé. Le fil principal pourrait ensuite le vérifier sur une base périodique.


4 commentaires

Le fil principal ne devrait pas attendre la réponse HTTP, il devrait simplement être interrompu dès qu'une réponse HTTP arrive. À n'importe quel temps ! S'il n'y avait pas de réponse, cela devrait continuer à exécuter normalement.


Je pense que je comprends maintenant. Je ne pense pas non plus qu'il y ait un moyen de faire ça ... du moins de manière propre. Je suppose que vous pourriez forcer une exception dans le fil pour que cela puisse arrêter ce que c'est faire. La reprise serait un problème. Cela me semble qu'il y a un problème architectural si les choses doivent fonctionner de cette façon.


Je pense que ce que Markw a dit, c'est raison. WaitforsingObject peut trier votre problème si je comprends votre question correctement.


Forcer l'exception serait ma deuxième pensée: définir un point d'arrêt dans la deuxième fonction de rappel de threads de telle sorte qu'il se casse dès qu'il y arrive.



0
votes

Si votre fil principal est le fil de l'interface graphique Pourquoi ne pas envoyer un message Windows? Que ce que nous faisons tous pour interagir avec GUI32 GUI des threads de travailleur.


3 commentaires

Le fil principal n'est pas un fil d'interface graphique. Cependant, le concept d'une file d'attente de message sonne bien! Malheureusement, il est également basé sur un "traction" -Mécanisme du fil principal au lieu d'un "push" -Mécanisme à partir du fil supplémentaire.


Oui, mais un qui fonctionne assez bien. Quel est votre fil principal de faire quand même?


Si votre thread n'est pas un fil d'interface graphique, vous pouvez utiliser la postTheadMessage pour obtenir le même résultat. Mais bien sûr, vous êtes libre d'utiliser tout mécanisme de file d'attente de message qui convient à vos besoins.



0
votes

Un moyen de faire cela qui est déterminé consiste à vérifier périodiquement si une réponse HTTP a été reçue.

Il vaut mieux que vous disiez ce que vous essayez d'accomplir.


0 commentaires


4
votes

Cela peut être l'un de ces moments où l'on travaille dans une idée très spécifique sans reconsidérer la plus grande image. Il n'y a pas de mécanisme singulier par lequel un seul thread peut arrêter d'exécuter dans son contexte actuel, aller faire quelque chose d'autre et reprendre l'exécution à la ligne exacte à partir de laquelle elle s'est arrêtée. Si c'était possible, il vaincre le but d'avoir des threads en premier lieu. Comme vous l'avez déjà mentionné, sans reculer et reconsidérer l'architecture globale, le plus élégant de vos options semble utiliser un autre thread pour attendre une réponse HTTP, le faire suspendre le fil principal dans un endroit sûr, traiter la réponse à son propre lieu. , puis reprendre le fil principal. Dans ce scénario, vous pourriez repenser si le stockage local de thread-local a toujours du sens ou si quelque chose d'une portée plus élevée est plus approprié, car vous pourriez potentiellement perdre beaucoup de cycles la copiant à chaque fois que vous interrompez le fil principal.


1 commentaires

Il est possible dans GNU / Linux avec des signaux; Dites-nous, comment vaincre-t-il le but d'avoir un thread différent en premier lieu?



0
votes

Dans cette situation, je ferais quelques choses. D'abord et avant tout, je rétrécirais le travail que le fil principal se fait pour être cassé dans des pièces aussi petites que possible. Cela vous donne une série d'endroits sûrs pour casser l'exécution. Ensuite, vous souhaitez créer une file d'attente de travail, probablement à l'aide de la cloche Microsoft. La clôte vous donnera la capacité d'avoir un fil en ajoutant tandis qu'un autre se lit sans avoir le besoin de verrouillage.

Une fois que vous avez cela en place, vous pouvez essentiellement faire fonctionner votre fil principal dans une boucle sur chaque morceau de travail, vérifiant périodiquement pour voir s'il y a des demandes à gérer dans la file d'attente. À long terme Qu'est-ce qui est agréable d'une architecture comme celle-ci, c'est que vous pourriez éliminer assez facilement le stockage localisé et paralléliser le fil principal en convertissant la flist en une file d'attente de travail (probablement toujours à l'aide de la fin de la fin) et de faire les petits morceaux de travail). et les réponses dans des objets de travail pouvant être distribués de manière dynamique dans tous les filets disponibles.


0 commentaires