模拟JavaScript中的上下文切换?
我一直在努力在JavaScript中实现一个非常复杂的系统,该系统需要模拟多线程进程等。 在真正的多线程进程中(例如内核线程),可以通过上下文切换在线程间切换。 这是可行的,因为您可以将当前进程的程序计数器存储并注册到临时结构,恢复程序计数器并注册其他进程,然后恢复之前进程中离开的地方。
我很好奇在JavaScript中是否可能有类似的东西。 我目前无法做到这一点,所以一直在使用协同式多任务设计系统。 特别是,我想要在多线程模拟器中运行的任何“函数”都被分解为一系列函数。 为了执行“函数”,我遍历函数数组,按顺序执行每个函数,同时保持“程序计数器”的下一个要执行的函数。 这允许我通过调用数组中的一个函数来模拟上下文切换,等待函数返回,然后切换到需要执行的其他函数数组。
我目前的方法可行,但在这个系统中编写代码很困难。 每个函数都必须具体指明它何时可以被中断,并且因为数组中的函数都是分开的,所以在函数的不同部分之间传递数据的逻辑很复杂。 我希望能够接近先发制人的多任务工作。
我的问题是: 是否可以通过外部源可以暂停和恢复的方式运行任意JavaScript函数?
检查StratifiedJS
首先重要的是要提到JavaScript是完全单线程的。 模拟多线程真的不是要走的路。 你依靠eventloops更好。
正如所提到的网络工作者可以使用,但它们并没有真正的跨浏览器合规性,所以我会忽略网络工作者。 你也不能对Web工作者进行任何DOM操作。
我会说看看node.js来推断为什么事件循环是多线程的一个很好的选择。 我相信他很好地谈到了为什么这是一个很好的选择。
所以相反,然后有一个函数数组并迭代它们,您可以创建一个事件并将一组函数绑定到它们并触发该事件。 backbone.js中可以找到一个非常轻量级的事件实现。
你不能只在JavaScript中暂停一个线程,因为只有一个。 如果没有功能的话,没有办法暂停或恢复功能。
只有一种方法来模拟这一点。 编写一个JavaScript分析器,将您的JavaScript很好地分离开来,并建立一个系统,让您暂停和恢复您的JavaScript。
以此功能为例
function(i) {
j = i + 1;
console.log(j);
return foo(j);
}
并将其转换为此
var bar = function(i) {
var r = {};
var j = i + 1;
var f = function() {
console.log(j);
var g = function() {
return foo(j);
};
onNext(g, arguments.callee, this, r);
};
onNext(f, arguments.callee, this);
return r;
}
您需要使用.suspend
和.resume
扩展Function
Function.prototype.suspend = function() {
this.__suspended = true;
}
Function.prototype.resume = function() {
this.__suspended = false;
}
function onNext(callback, function, context, returnObj) {
if (!function.__suspended) {
var cb = function() {
Backbone.Events.unbind("run", cb);
returnObj.r = callback.call(this);
}
Backbone.Events.bind("run", cb);
}
}
setInterval(function() {
Backbone.Events.trigger("run");
}, 5);
你也将不得不用var a = b()
替换所有引用
callFunctionAsync(b, context, args, function(return) {
var a = return;
...
});
我将离开你的实施。 现在所有的函数都返回一个对象r
并且只有当rr
被设置为一个值时,它才会“返回”。 因此,通过检查rr
是否已设置以及是否触发了函数异步回调,只需检查事件循环是否已“返回”。
嘿,看看我们有什么。 通过在事件循环中运行它们来模拟线程。 在代码中本地使用事件循环,而不是通过它模拟线程会更好。
基本上让你的函数在再次绕过事件循环时运行它的代码的下一行。 并检查当你绕过你的eventloop时,特定的“功能”是暂停还是恢复。
为了简洁起见,我没有实现将函数返回到“函数”。 这不应该太难仿效。
要么直接使用事件循环,要么使用假的线程方法,并获得一个编译器来编译代码,以便在代码编写时看起来不可怕。
如果你造成死锁,祝你好运。
链接地址: http://www.djcxy.com/p/55303.html上一篇: Simulating context switches in JavaScript?
下一篇: How do I bootstrap a collection in Backbone.js using Javascript only