【问题标题】:Sharing variables between web workers? [global variables?]在网络工作者之间共享变量? 【全局变量?】
【发布时间】:2020-03-24 22:42:39
【问题描述】:

我有什么方法可以在两个网络工作者之间共享一个变量吗? (Web Worker 基本上是 Javascript 中的线程)

在像 c# 这样的语言中,你有:

public static string message = "";
static void Main()
{
 message = "asdf";
 new Thread(mythread).Run();
}
public static void mythread()
{
 Console.WriteLine(message); //outputs "asdf"
}

我知道这是一个不好的例子,但在我的 Javascript 应用程序中,我有一个线程在执行繁重的计算,可以分布在多个线程中 [因为我有大量的数组形式的数据。数组的所有元素都是相互独立的。换句话说,我的工作线程不必关心锁定或类似的事情]

我发现在两个线程之间“共享”一个变量的唯一方法是创建一个 Getter/setter [通过原型],然后使用 postMessage/onmessage...虽然这看起来效率很低 [尤其是对于对象,我必须将 JSON 用于 AFAIK]

LocalStorage/Database 已从 HTML5 规范中删除,因为它可能导致死锁,所以这不是一个选项 [可悲]...

我发现的另一种可能性是使用 PHP 实际上有一个 getVariable.php 和 setVariable.php 页面,它们使用 localstorage 来存储 ints/strings...再次,对象 [包括数组/null] 必须被转换成 JSON……然后,JSON.parse()'d。

据我所知,Javascript 工作线程与主页面线程完全隔离[这就是 Javascript 工作线程无法访问 DOM 元素的原因

虽然 postMessage 有效,但速度很慢。

【问题讨论】:

  • 你可以使用sharedArrayBuffer,它会在发送到postMessage时被克隆。这是一篇关于它的文章link

标签: javascript html global-variables local-storage web-worker


【解决方案1】:

网络工作者是故意不共享的——工作者中的所有内容都对其他工作者和浏览器中的页面完全隐藏。如果有任何方法可以在工作人员之间共享非“原子”值,那么这些值的语义几乎不可能用于可预测的结果。现在,可以在某种程度上引入锁作为使用这些值的一种方式——你获取锁,检查并可能修改值,然后释放锁——但是锁非常棘手使用,并且由于通常的故障模式是死锁,你可以很容易地“砖化”浏览器。这对开发人员或用户来说都不是好事(尤其是,当您考虑到 Web 环境非常适合甚至从未听说过线程、锁或消息传递的非程序员进行实验时),所以另一种方法是在浏览器中的工作人员或页面之间不共享状态。您可以将消息(可以认为是“通过网络”序列化到工作人员,然后根据序列化信息创建自己的原始值副本)传递消息,而无需解决任何这些问题。

确实,消息传递是支持并行性而又不会让并发问题完全失控的正确方法。正确安排您的消息传递,您应该拥有尽可能多的权力,就好像您可以共享状态一样。你真的不想要你认为你想要的替代品。

【讨论】:

  • 如果有任何方法可以在工作人员之间共享非“原子”值,那么这些值的语义将无法用于可预测的结果。
  • Lamport 的烘焙算法。 Dijkstra 保护命令逻辑。这一切都专门用于非确定性可预测性。
  • 好吧,“几乎不可能”。共享非简单数据很容易出错,这仍然是事实,因此网络工作者无法做到这一点。
  • 您真正想说的是,该领域大多数程序员的经验和领域知识将导致几乎无法预测的结果。在编程中,所有的权力都伴随着责任;或模式来降低风险。 :p
  • 当然。鉴于网络上的大部分代码都被大量垃圾污染了,我认为我有理由怀疑网络开发人员是否有能力正确使用任何类型的东西。
【解决方案2】:

不可以,但您可以向网络工作者发送消息,这些消息可以是数组、对象、数字、字符串、布尔值和 ImageData 或这些的任意组合。 Web Worker 也可以发回消息。

【讨论】:

    【解决方案3】:

    有两个选项可以在专用工作人员之间共享数据:

    1. Shared Workers

    SharedWorker 接口代表一种特定类型的工作者, 可以从多个浏览上下文访问,例如几个 windows、iframe 甚至是 worker。

    Spawning a Shared Worker in a Dedicated Worker

    2。 Channel Messaging API

    Channel Messaging API 允许在其中运行两个单独的脚本 附加到同一文档的不同浏览上下文(例如,两个 IFrames,或者说主文档和一个IFrame,两个文档通过一个 SharedWorker,或两个worker)直接通信,通过 通过双向通道(或管道)相互之间的消息 每端都有一个端口。

    How to call shared worker from the web worker?

    【讨论】:

    • 共享工作者是可以在消息网络中链接的工作者,而不是专用工作者的简单消息树。但是工人的基本原则是正确的:工人之间不能共享任何东西,只能传递消息。
    【解决方案4】:

    我最近读到(但没有使用)shared workers。根据Share the work! Opera comes with SharedWorker support 的说法,仅支持最新的浏览器(Opera 10.6、Chrome 5、Safari 5)。

    【讨论】:

      猜你喜欢
      • 2021-08-07
      • 1970-01-01
      • 2019-08-17
      • 1970-01-01
      • 2018-02-13
      • 2013-12-09
      • 1970-01-01
      • 1970-01-01
      • 2017-08-19
      相关资源
      最近更新 更多