JavaScript中的多线程用于游戏开发

7
我考虑使用纯JavaScript和html5开发游戏,不使用任何第三方插件。我遇到的问题是无法将游戏的不同“模块”分离为不同的线程,例如渲染作业、游戏逻辑、资产加载等等。

Web Workers似乎可以将代码分离为不同的线程,但问题在于它们之间可以传递的信息有限。例如,对于渲染作业,我需要传递整个“世界”,包括所有实体、网格、贴图等,以便每次更新游戏时都能使用,因为工作线程不能共享内存。可以进行优化,例如只在初始化时发送静态对象(网格、纹理),然后只在更新时发送一个对象的状态 (它的世界变换),但这仍然不是理想的。

是否有一种方法可以在它们之间发送大数据或共享一些对象呢?或者是否有完全不同的方法来实现真正的多线程?我知道使用插件/齿轮可以更容易地实现这一点,但我需要使用仅在开放web上可用的方法。

虽然我不否认使用JavaScript实现"真正"的并行性的合理性,但是你提出问题的方式让我建议你去了解一下基于事件的编程模型。举个例子(用该模型开发的软件,都不是用JS写的),基于事件的nginx web服务器在重负载下远远超过基于线程的Apache。这只是一个例子,证明JavaScript部分有意地不使用传统的并行性方法,并解释了为什么"webworkers"还没有被广泛应用/支持。 - Mörre
5个回答

6
JavaScript的Web Worker在某些方面是更好的并发编程模型。例如,它是事件驱动的,并且没有共享对象。这意味着您不能陷入死锁(因为根本没有锁定),一个对象不能被两个线程同时修改而进入无效状态。
问题是您不能轻松地将传统游戏系统堆叠在这个模型之上。因此,您需要以一种新的方式设计游戏系统以采用这种编程模型,而我认为这可能代价高昂。

4

我所说的工作线程是指Web Workers。我进行了一些小修改以澄清这一点。就像我说的,工作线程似乎能够实现多线程,但在它们之间共享信息的方式上存在问题。 - Colin Dumitru
好的,确实没有其他方法。JS中运行“并行”任务的第一种方法是基于事件的编程。当然,这只使用一个CPU(-核心),但在这个限制范围内,它可以非常好地扩展。最近添加的Web Workers(就实际可用性而言)是迄今为止唯一实用的方法,可以使用一块(JS)软件扩展到超过一个CPU(核心)。 - Mörre

0

在 JavaScript 中,如果没有 Web Workers,我不知道有什么真正的方法来进行多线程。

但你可以使用一些逻辑来优先处理某些任务所需的时间。你可以编写将信息存储在状态中的函数(因此循环可以在稍后的时间退出并重新启动)。每个循环只知道在保存其状态并退出函数之前它还有多少时间。

所以 for 循环也会有一个时间条件...

//Loop over some iterator, exit if time is up
for (i = 1; i < max || timeNotUp(); i++)
{
}

//If exiting normally 
if (i == max)
{ //do somthing
}
//otherwise, save state
else
{
    this.i = i;
    this.otherStuff = otherStuff;
}

你可以通过这种方式优先处理你的代码。但是,这样做存在一些缺点。保存状态不会带来干净易于跟踪的代码(特别是当有多个嵌套循环时)。而且由于需要不断检查时间和保存状态,它也不够快速。


0

Web Workers 是 JavaScript 中最接近多线程的技术。
目前来说。
就是这样。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接