0

我想在我的 sinatra 应用程序中以线程安全的方式存储和更新枚举。我用独角兽。我尝试了以下方法:

#!/usr/bin/ruby

require 'sinatra'

$locked = false
$num = 0
class App < Sinatra::Base
  before do
    while $locked do end
    $locked = true
  end

  after do
    $locked = false
  end

  get "/wait" do
    sleep 10
    $num += 1
    erb :display
  end

  get "/winner" do
    $num += 1
    erb :display
  end
end

该视图仅显示 $num ;)

我用独角兽(4 个工人)启动了这个应用程序,并http://localhost:8080/winner用我的浏览器访问了。我点击了几次刷新,但应用程序没有显示预期的行为(1,2,3,4,5,...)而是显示随机数(1,1,2,1,2,3, 2,3,2,3,4,...)

那么我如何获得这个线程安全的呢?:D(对不起我的英语不好)

4

1 回答 1

1

您的问题不在于线程安全(尽管这里有轻微的竞争条件 - 使用互斥锁而不是您的 $locked 变量),因为每个独角兽工作者都是一个单独的进程。

这些进程中的每一个都有一组单独的全局变量,因此无论您为每个进程添加多少同步,您编写的代码基本上都无法工作。

解决这个问题的常用方法是将数字存储在一些共享数据存储中,例如 mysql、mongo、redis 甚至 memcached 等数据库。其中最后 3 个具有特定的原子创建或增量操作,但您也可以在关系数据库中执行此操作。

于 2012-10-08T16:07:22.593 回答