【问题标题】:Mutual Exclusion for N Asynchronous ThreadsN个异步线程的互斥
【发布时间】:2010-09-12 02:45:23
【问题描述】:

我有一个异步应用程序,这意味着在任何给定时间都可以有 N 个事件。是否有一种已知的算法可以对 N 个线程进行互斥,而无需将每个线程硬编码为具有 ID?

【问题讨论】:

  • 一个需要这样做的例子是使用本地存储,它是非事务性的,因此如果在多个选项卡中打开同一个页面是不安全的。使用共享工作者实现互斥行为可以解决该限制。

标签: javascript multithreading asynchronous


【解决方案1】:

我不认为 Javascript 本身有对象锁定 - 因为 Javascript 基本上是单线程的。您可能能够找到一个运行多个 Javascript 代码线程的库或实现——但它们是否都在同一个变量空间中运行?他们将需要以某种方式相互交流。

假设您的多个线程可以以某种方式共享一个静态 mutex 变量,并且只要您假设++”被认为是系统的原子操作正在做你的线程,这个怎么样?

int mutex = 0;
mutuallyExclusiveOperation(){
  succeed=false;
  while(!succeed){
    while(mutex>0){ sleep();  }
    m=mutex++;   //"Simultaneously" read and increment
    if(m>0)mutex--;
    else{
      doMutuallyExclusiveThing();
      succeed=true;
      mutex--;
    }
 }
}

【讨论】:

  • 我可以做一个静态变量没问题,我担心的不是我不确定 ++ Was 是一个原子操作。不知道 JS 是不是这样?如果这是真的,这个问题(我相信)是可以解决的。实际上,您的函数看起来是正确的。
  • 从今天开始,chrome 不再是单线程的了。试试这个例子,它将使用 100% 的处理器:jsfiddle.net/MTJ27/15
  • 您提供的代码可以原样使用吗?我的意思是完全正确,可以在生产模式下使用?
  • 我希望++ 的行为取决于使用的 Javascript 解释器。如果我用这段代码启动宇宙飞船,我会 a) 在要使用的特定浏览器上运行大量线程密集的测试,b) 检查解释器代码本身。如果解释器的多个实例在单独的真实操作系统线程中运行,正如@darkzagnel 建议的那样,那么也许没有万无一失的解决方案的希望,除非你能找到一个真正的原子 JS 读写操作。
  • 实际上,不要担心互斥锁之类的东西。仅当您使用 worker 并且 worker 不与您的代码共享其数据时,Chrome 才是多线程的。您必须使用端口和信号将数据传递给它。他们无权访问 dom、窗口、文档或任何其他变量。
【解决方案2】:

JavaScript 通常是单线程的,所以你永远不会有两段代码同时修改相同的数据。您可以使用 Web Worker 在现代浏览器中使用多个线程,但它们只能通过传递消息进行通信,而不是共享内存,因此如果您使用 Web Worker,则无需担心互斥。

【讨论】:

  • 我实际上是在使用网络工作者,但这不是重点。我担心的是 onMessage 函数是否被调用了两次。虽然它可能是“单线程”的,但如果它们最终在同一时间段内运行,它是否会间歇性地将两个调用线程化?
  • @Michael 您试图通过互斥来保护对什么资源的访问?
  • 假设我有一些全局数组,我需要在其中存储一些东西,并返回存储的项目的索引。通常,我会检查长度,将其推送到数组中,然后返回数组的长度。但是,如果第二个线程(由于异步事件而被调用)在获取数组长度和将新值推送到数组之间进行线程化,并且自己执行相同的操作,则第一个函数将返回错误的索引。
【解决方案3】:

可以是单线程的,但有时当某些用户操作运行我们希望避免的多个线程时会出现问题(例如 AJAX 请求)。如果我们想制作一个信号量,我们可以使用一个全局变量。无论如何,我确定不应该这样做——我只是不知道有什么更好的解决方案,因为我对 JS 的参与度并不高。

希望它能在一些简单的情况下对您有所帮助:

<html>

 <head>
  <script type="text/javascript">
        var magic_global;
        magic_global = true;

        function magic_switch() {
                magic_global = !magic_global;
        }
  </script>
 </head>

 <body>
        <a href="#" onclick="magic_switch();">switch Magic</a>
        <a href="#" onclick="alert(magic_global);">show the Magic</a>
 </body>

</html>

【讨论】:

    猜你喜欢
    • 2014-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-04
    • 1970-01-01
    • 1970-01-01
    • 2020-06-07
    • 2013-01-31
    相关资源
    最近更新 更多