2010-07-05 4 views
8

J'utilise des travailleurs Web pour effectuer un travail intensif du processeur, mais j'ai l'exigence que le travailleur répondra aux messages du script parent alors que le worker est traitement en cours.Comment empêcher HTML5 Web Workers de se verrouiller ainsi répondre correctement aux messages du parent

Le travailleur ne répondra cependant pas aux messages alors qu'il est verrouillé dans une boucle de traitement, et je n'ai pas trouvé un moyen de dire interroger la file d'attente des messages. Il semble donc que la seule solution consiste à interrompre le traitement à un intervalle pour permettre à tous les messages de la file d'être traités. Les options évidentes sont d'utiliser une minuterie (par exemple avec setInterval) mais j'ai lu que le délai minimum entre les tirs est assez long (http://ajaxian.com/archives/settimeout-delay) ce qui est regrettable car cela va ralentir le traitement beaucoup.

Quelles sont les pensées des autres à ce sujet? Je vais essayer d'avoir le travailleur onmessage à lui-même à la fin de chaque onmessage, mettant ainsi efficacement en œuvre une étape de la boucle de traitement par événement reçu de lui-même, mais je voulais juste voir si quelqu'un avait des idées à ce sujet.

Merci,

+0

Accrocher https://stackoverflow.com/a/32269593/632951 – Pacerier

Répondre

6

Un travailleur peut générer des sous-travailleurs. Vous pouvez faire en sorte que votre travail principal agisse en tant que votre file d'attente de messages, et lorsqu'il reçoit une demande pour une opération longue, générer un sous-worker pour traiter ces données. Le sous-worker peut ensuite renvoyer les résultats au worker principal pour supprimer l'événement de la file d'attente et renvoyer les résultats au thread principal. De cette façon, votre opérateur principal sera toujours libre d'écouter les nouveaux messages et vous aurez un contrôle total sur la file d'attente.

--Nick

+1

Je pense que cela ne fonctionnera pas si le calcul doit être arrêté et repris. Je n'ai pas encore trouvé de solution pour cela. Exemple: http: //gist.github.com/607058 – Giacomo

+0

@nciagra, Cette réponse ne fonctionne pas: vous avez simplement poussé le problème d'un cran vers le haut. Alors, que faire si vous générez des sous-travailleurs? Maintenant, ces sous-travailleurs sont occupés à faire le calcul et vous ne pouvez pas les interrompre de votre mainworker. Je suppose que [l'ancienne solution d'intervalle] (https://stackoverflow.com/a/10180450/632951) (maintenant dans le webworker lui-même) est le seul moyen si nous avons besoin d'interrompre le travailleur, les webworkers ont sérieusement besoin d'un véritable mécanisme d'interruption comme quoi Java peut faire. – Pacerier

0

le même problème, je cherchai les travailleurs web et rédiger trouvé quelque chose dans la section Processing model, pas de 9 à 12. Pour autant que je l'ai compris, un travailleur qui commence le traitement d'une tâche sera n'en traite pas une autre jusqu'à ce que la première soit terminée. Donc, si vous ne vous souciez pas d'arrêter et de reprendre une tâche, la réponse de nciagra devrait donner de meilleures performances que de replanifier chaque itération de la tâche.

Toujours en train d'enquêter.

+0

La réponse de nciagra ne fonctionne pas. – Pacerier

3

J'ai moi-même rencontré ce problème lorsque je jouais avec des travailleurs pour la première fois. J'ai également débattu de l'utilisation de setInterval, mais j'ai estimé que ce serait une approche plutôt hacky du problème (et je l'avais déjà fait de cette façon pour mon multithreading émulé). Au lieu de cela, je me suis contenté de mettre fin aux travaux du thread principal (worker.terminate()) et de les recréer si la tâche à laquelle ils sont impliqués doit être interrompue. Garbage collection, etc semblait être géré dans mes tests.

S'il existe des données de ces tâches que vous souhaitez enregistrer, vous pouvez toujours les renvoyer au thread principal pour le stockage à intervalles réguliers, et s'il existe une logique que vous souhaitez implémenter pour savoir si elles sont terminées ou non , vous pouvez afficher les données pertinentes à intervalles réguliers pour l'autoriser.

Les sous-traitants de frai entraîneraient de toute façon le même ensemble de problèmes; vous devrez encore terminer les sous-traitants (ou en créer de nouveaux) selon une certaine logique, et je ne suis pas sûr que ce soit aussi bien supporté (sur le chrome par exemple).

James

+1

ayant le même problème, et utilisé la même solution. Pour ne pas perdre les calculs effectués par le webworker Je poste des données calculées à quelques intervalles de la "fenêtre" parent, puis quand je répète le webworker je commence par le résultat calculé jusqu'ici – Picard

+0

Malheureusement, worker.terminate() perd de la mémoire. .. il pourrait fonctionner si utilisé de façon sporadique, mais dans mon cas particulier, il bloque le navigateur très rapidement https://bugs.chromium.org/p/chromium/issues/detail?id=502298 – solendil

Questions connexes