10

我有什么办法可以在两个网络工作者之间共享一个变量吗?(网络工作者基本上是 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 来存储整数/字符串......再次,必须将对象 [包括数组/null] 转换为JSON...然后是 JSON.parse()'d。

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

尽管 postMessage 有效,但速度很慢。

4

4 回答 4

15

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

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

于 2010-02-18T09:03:18.023 回答
5

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

于 2010-02-14T21:30:23.550 回答
5

在专用工作人员之间共享数据有两种选择:

1.共享工作者

SharedWorker 接口代表一种特定类型的工作人员,可以从多个浏览上下文中访问,例如多个窗口、iframe 甚至工作人员。

在 Dedicated Worker 中生成 Shared Worker

2.频道消息 API

Channel Messaging API 允许在附加到同一个文档的不同浏览上下文中运行的两个单独的脚本(例如,两个 IFrame,或主文档和一个 IFrame,通过 SharedWorker 的两个文档,或两个工作人员)直接通信,在一个之间传递消息另一个通过两端各有一个端口的双向通道(或管道)。

如何从网络工作者调用共享工作者?

于 2015-06-16T18:43:37.503 回答
2

我最近阅读了(但没有使用过)shared workers。根据分享作品!Opera 带有 SharedWorker 支持,仅支持最新的浏览器(Opera 10.6、Chrome 5、Safari 5)。

于 2010-08-30T14:34:14.423 回答