简体   繁体   中英

Thread mutex lock doesn't seem to block

I have the following little Sinatra program. It simply prints the current epoch time and then sleeps for one second before returning:

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

I would expect the mutex to force the web requests to be handled sequentially. However, this does not seem to be the case according to this test:

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

As you can see, the result of five simultaneous requests all produce the same epoch time.

What am I doing wrong?

Sinatra has a single request concurrency lock option:

require 'rubygems'
require 'sinatra'

set :lock, true

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

I think I figured it out. The stream call starts a background job which returns immediately. So the mutex is unlocked quickly, allowing a new request to be processed.

Moving the code outside of the stream block fixes it:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM