我想在我的sinatra应用程序中以线程安全的方式存储和更新Enum。我用独角兽。我尝试了以下方法:
#!/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 (抱歉我的英语不好)
答案 0 :(得分:1)
你的问题不是线程安全(尽管这里有一个轻微的竞争条件 - 使用互斥锁而不是你的$ locked变量)因为每个独角兽工作者都是一个独立的过程。
这些进程中的每一个都有一组独立的全局变量,因此无论您为每个进程添加多少同步,您从根本上编写的代码都无法工作。
解决这个问题的方法是将数字存储在某些共享数据存储区中,例如mysql,mongo,redis甚至memcached等数据库。其中最后3个具有特定的原子创建或增量操作,但您也可以在关系数据库中执行此操作。