Javascript信号量/测试和设置/锁定?

Javascript信号量/测试和设置/锁定?,javascript,concurrency,semaphore,Javascript,Concurrency,Semaphore,Javascript中是否存在原子测试和设置、信号量或锁 我使用javascript通过自定义协议调用异步后台进程(后台进程实际上在单独的进程中运行,与浏览器无关)。我相信我正在进入比赛状态;后台进程在我的测试和集合之间返回,在javascript端把事情搞砸了。我需要一个测试和设置操作,使它成为一个真正的信号量 下面是试图检测后台进程并将其排队的javascript代码: Call = function () { var isRunning = true, queue = [];

Javascript中是否存在原子测试和设置、信号量或锁

我使用javascript通过自定义协议调用异步后台进程(后台进程实际上在单独的进程中运行,与浏览器无关)。我相信我正在进入比赛状态;后台进程在我的测试和集合之间返回,在javascript端把事情搞砸了。我需要一个测试和设置操作,使它成为一个真正的信号量

下面是试图检测后台进程并将其排队的javascript代码:

Call = function () {

var isRunning = true,
    queue = [];

return  {
    // myPublicProperty: "something",

    call: function (method) {
            if (isRunning) {
                console.log("Busy, pushing " + method);
                queue.push(method);
            } else {
                isRunning = true;
                objccall(method);
            }
        },

        done: function() {
            isRunning = false;
            if (queue.length > 0) {
                Call.call(queue.shift());
            }
        }
    };
}();
Call是实现排队的单例;任何想调用外部进程的人都会调用.Call(“某物”)


有什么想法吗?

也许您可以实现一个基本的整数信号量,只需将变量添加到DOM中并锁定/解锁它,确保您的函数不断检查它,否则超时=)


如果您使用的是Mootools之类的框架,您可以尝试使用onComplete等事件处理应用程序流。

JavaScript没有锁定语义,因为JS不是多线程语言。多个线程只能在完全不同的上下文中并发运行——例如HTML5工作线程,或者在JavaScriptCoreAPI的上下文对象的多个实例中(我假设SpiderMonkey具有类似的概念)。它们不能有共享状态,所以本质上所有的执行都是原子的

好的,由于您现在提供了一些代码,我假设您有一些类似于:

External Process:
<JSObject>.isRunning = true;
doSomething()
<JSObject>.done()
外部过程:
.isRunning=true;
doSomething()
.完成
或者一些类似的(使用适当的API)。在这种情况下,如果JS在JS对象的上下文中执行(JavaScriptCore就是这么做的),我希望JS引擎会阻止它,否则您可能需要在JS执行时手动锁定


你用什么引擎来做这些?我这样问是因为根据您的描述,您似乎在使用非JS语言提供的C/C++API从非JS语言的辅助线程设置标志,而大多数JS引擎都假设通过API进行的任何状态操作都将在单个线程上发生,通常,所有执行都发生在同一个线程上。

我有ajax功能,可以填充选择列表,我需要锁定它,所以我做了类似的事情。我想你可以用延迟和管道之类的方法来简化

var semaphore=[];

function myFunc(arg){
   var dfd;
   $.when(semaphore[table]).done(
      function(){
            dfd=myFuncInner(arg);
      }
      );
return dfd;
}

function myFuncInner(table){
semaphore[arg] = new $.Deferred();
... 
somethingasynchronous({
    semaphore[arg].resolve();
});

return  semaphore[arg];
}

首先,虽然javaScript是单线程的,但javaScript应用程序不需要任何序列化机制

一个简单的例子是,提交按钮应该在向服务器发出Ajax请求的一段时间内淡出。当异步Ajax请求成功完成时,应该在按钮所在的位置显示一条消息

虽然能够取消按钮的淡出并简单地将其样式设置为“display:none”会很好,但一旦Ajax请求完成,这在jQuery中是不可能的。此外,解决方案可以使用事件来同步两个同时进行的活动,但对于一个简单的问题来说,这实际上是过火了

一个低技术的解决方案是轮询一个锁,当淡出完成时,它将被解锁,但“服务器完成”消息不会显示,直到执行由$.post设置的成功回调

var gl_lock;
var gl_selfID;

function poll_lock(message) {
     if (gl_lock === 0) {
          $('#output').text(message).fadeIn(200);
          window.clearInterval(gl_selfID);
     }
 } // end of poll_lock

 function worker() {

     // no one gets in or out
     gl_lock = 1;

     $.post(..., data,function() { 
           gl_selfID = window.setInterval(poll_lock, 40, data.message);
      }, "json");

     // end of fadeout unlock the semaphore
     $('#submit-button').fadeOut(400, function() { gl_lock = 0; });

  } // end of worker

最后,我认为这是一个更详细的答案,与perrohunter在本次讨论中提出的思路一致。

我不确定问题的确切含义,但请查看我的信号量对象:。

我也有同样的问题,下面是我如何解决的。它适用于两个并发进程。如果您有三个或三个以上的流程,则两个流程可能同时启动

var isRunning = false;
...
var id = setInterval(function(){ //loop until isRunning becomes false
            if (!isRunning){
                isRunning = true;
                //do something synchronous or use a promise
                isRunning = false;
                clearInterval(id); // stop the loop here
            }
        , 10);

它比while循环更好,因为它解决了读取/设置
isRunning
的并发/异步问题

您可能希望更详细地指定您的“流程”。这是服务器端javascript吗?javascript代码始终是原子的,所以不需要锁定或其他任何东西。请看。我添加了上面的完整代码以使其更加清晰。引擎是Webkit(safari)。我从javascript调用外部进程,外部进程在完成时调用“done”方法。基本上,我需要确保一次只运行一个外部进程。假设您正在执行类似于[someObject call]或JSObjectCallAsFunction(context、doneFunction、someObject)的操作,那么应该确保您正在调用主线程,特别是如果您使用的是WebKit提供的ObjC JS API(IIRC它可能绕过一些锁)你有没有在iPhone上使用过webkit sdk?我使用的是一个简单的window.location方案,还没有尝试过sdk。我很想了解更多关于sdk的信息。没有,我对iPhone sdk知之甚少——我只知道JSC的C api:DYes。在项目html页面中有一些使用示例。这看起来不像是一个信号量,是吗看起来更像是一个任务计划程序,它在对任务排队之前允许一定程度的并行性。要成为一个信号量,您需要能够阻止,直到资源可用。它确实会阻止,但可能我不清楚这意味着什么。它不会“阻止”,它将控制权交给javascript调度程序,然后稍后恢复。但它看起来和行为都像是来自外部的信号量。在内部,它比阻塞信号量“更聪明”。