如何防止 HTML5 Web Workers 锁定从而正确响应来自父级的消息
我正在使用网络工作线程来执行一些 CPU 密集型工作,但要求工作线程在仍在处理时响应来自父脚本的消息。
然而,当工作线程被锁定在处理循环中时,它不会响应消息,并且我还没有找到一种方法来轮询消息队列。因此,似乎唯一的解决方案是每隔一段时间中断处理,以允许队列中的任何消息得到服务。
明显的选择是使用计时器(例如 setInterval),但是我读到触发之间的最小延迟相当长(http://ajaxian.com/archives/settimeout-delay) 不幸的是,它会大大减慢处理速度。
其他人对此有何看法?我将尝试让工作人员在每个 onmessage
结束时将 onmessage
分派给自身,从而有效地实现从自身接收到的每个事件的处理循环的一步,但是只是想看看是否有人对此有任何想法。
谢谢,
I'm using web workers to do some CPU intensive work but have the requirement that the worker will respond to messages from the parent script while the worker is still processing.
The worker however will not respond to messages while it is locked in a processing loop, and I have not found a way to say poll the message queue. Thus it seems like the only solution is to break processing at an interval to allow any messages in the queue to be serviced.
The obvious options are to use a timer (say with setInterval) however I have read that the minimum delay between firings is quite long (http://ajaxian.com/archives/settimeout-delay) which is unfortunate as it will slow down processing alot.
What are other peoples thoughts on this? I'm going to try have the worker dispatch onmessage
to itself at the end of each onmessage
, thus effectively implementing one step of the processing loop per event received from itself, but just wanted to see if anyone had any ideas about this.
Thanks,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
一个工人可以产生子工人。您可以让主工作线程充当消息队列,当它收到长时间运行操作的请求时,生成一个子工作线程来处理该数据。然后,子工作线程可以将结果发送回主线程,以从队列中删除事件并将结果返回到主线程。这样,您的主要工作人员将始终可以自由地侦听新消息,并且您可以完全控制队列。
- 缺口
A worker can spawn sub workers. You can have your main worker act as your message queue, and when it receives a request for a long running operation, spawn a sub worker to process that data. The sub worker can then send the results back to the main worker to remove the event from the queue and return the results to the main thread. That way your main worker will always be free to listen for new messages and you have complete control over the queue.
--Nick
我自己第一次和工人一起玩时就遇到了这个问题。我还讨论过使用 setInterval,但我觉得这将是解决问题的一种相当老套的方法(并且我已经在模拟多线程中采用了这种方法)。相反,我决定从主线程 (worker.terminate()) 终止工作人员,并在需要中断它们所涉及的任务时重新创建它们。垃圾收集等似乎在我的测试中得到了处理。
如果您想要保存这些任务中的数据,您可以随时将其发送回主线程进行存储,并且如果您希望实现一些关于它们是否终止的逻辑,您可以发送相关数据以足够定期的间隔返回,以允许这样做。
无论如何,生成 subworker 都会导致同样的问题;您仍然必须根据某种逻辑终止子工作人员(或创建新的子工作人员),并且我不确定它是否得到很好的支持(例如在 chrome 上)。
詹姆斯
I ran into this issue myself when playing with workers for the first time. I also debated using setInterval, but I felt that this would be a rather hacky approach to the problem (and I had already went this way for my emulated multithreading). Instead, I settled on terminating the workers from the main thread (worker.terminate()) and recreating them if the task that they are involved in needs to be interrupted. Garbage collection etc seemed to be handled in my testing.
If there is data from these tasks that you want to save, you can always post it back to the main thread for storage at regular intervals, and if there is some logic you wish to implement regarding whether they are terminated or not, you can post the relevant data back at regular enough intervals to allow it.
Spawning subworkers would lead to the same set of issues anyway; you'd still have to terminate the subworkers (or create new ones) according to some logic, and I'm not sure it's as well supported (on chrome for example).
James
遇到同样的问题,我搜索了网络工作人员草稿,并在 处理模型 部分,从 9 到 12 的步骤。据我了解,开始处理任务的工作人员在第一个任务完成之前不会处理另一个任务。因此,如果您不关心停止和恢复任务,nciagra 的答案应该比重新安排任务的每次迭代提供更好的性能。
不过仍在调查中。
Having the same problem I searched the web workers draft and found something in the Processing model section, steps from 9 to 12. As far as I have understood, a worker that starts processing a task will not process another one until the first is completed. So, if you don't care about stopping and resuming a task, nciagra's answer should give better performances than rescheduling each iteration of the task.
Still investigating, though.