线程互斥锁似乎没有阻塞

时间:2013-09-10 19:05:09

标签: ruby multithreading sinatra

我有以下小Sinatra程序。它只是打印当前的纪元时间,然后睡一秒,然后返回:

require 'rubygems'
require 'sinatra'

get '/' do
    Thread.new do 
        $mutex.synchronize do
            stream do |out|
                out << "\n" << Time.now.to_i 
                sleep 1
            end
        end
    end.join
end

$mutex = Mutex.new

我希望互斥锁能够强制顺序处理Web请求。但是,根据这项测试,情况似乎并非如此:

$ for i in $(seq 5) ; do curl localhost:4567/ & disown; done
1378839480
1378839480
1378839480
1378839480
1378839480

如您所见,五个同时发出的请求的结果都产生相同的纪元时间。

我做错了什么?

2 个答案:

答案 0 :(得分:2)

Sinatra有一个single request concurrency lock选项:

require 'rubygems'
require 'sinatra'

set :lock, true

get '/' do
  time = Time.now.to_i
  sleep 1
  time.to_s
end

答案 1 :(得分:1)

我想我明白了。流调用启动后台作业,该作业立即返回。因此,互斥锁可以快速解锁,允许处理新请求。

将代码移到流块之外会修复它:

get '/' do
    Thread.new do 
        $mutex.synchronize do
            result = "\n" + Time.now.to_i
            sleep 1
            stream do |out|
                out << result
            end
        end
    end.join
end