Ruby on Rails 入门之:(19) ruby线程同步控制
2012-10-10 12:04
495 查看
在Ruby中,提供三种实现同步的方式,分别是:
1. 通过Mutex类实现线程同步
2. 监管数据交接的Queue类实现线程同步
3. 使用ConditionVariable实现同步控制
通过Mutex类实现线程同步控制,如果在多个线程钟同时需要一个程序变量,可以将这个变量部分使用lock锁定。
代码如下:
[ruby] view
plaincopy
#encoding:gbk
require "thread"
puts "Synchronize Thread"
@num=200
@mutex=Mutex.new
def buyTicket(num)
@mutex.lock
if @num>=num
@num=@num-num
puts "you have successfully bought #{num} tickets"
else
puts "sorry,no enough tickets"
end
@mutex.unlock
end
ticket1=Thread.new 10 do
10.times do |value|
ticketNum=15
buyTicket(ticketNum)
sleep 0.01
end
end
ticket2=Thread.new 10 do
10.times do |value|
ticketNum=20
buyTicket(ticketNum)
sleep 0.01
end
end
sleep 1
ticket1.join
ticket2.join
程序运行的输出:
[ruby] view
plaincopy
Synchronize Thread
you have successfully bought 15 tickets
you have successfully bought 20 tickets
you have successfully bought 15 tickets
you have successfully bought 20 tickets
you have successfully bought 15 tickets
you have successfully bought 20 tickets
you have successfully bought 15 tickets
you have successfully bought 20 tickets
you have successfully bought 15 tickets
you have successfully bought 20 tickets
you have successfully bought 15 tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
除了使用lock锁定变量,还可以使用try_lock锁定变量,还可以使用Mutex.synchronize同步对某一个变量的访问。
SizedQueue类能够非常便捷的帮助我们开发线程同步的应用程序,应为只要加入到这个队列中,就不用关心线程的同步问题。
经典的生产者消费者问题:
[ruby] view
plaincopy
#encoding:gbk
require "thread"
puts "SizedQuee Test"
queue = Queue.new
producer = Thread.new do
10.times do |i|
sleep rand(i) # 让线程睡眠一段时间
queue << i
puts "#{i} produced"
end
end
consumer = Thread.new do
10.times do |i|
value = queue.pop
sleep rand(i/2)
puts "consumed #{value}"
end
end
consumer.join
程序的输出:
[ruby] view
plaincopy
SizedQuee Test
0 produced
1 produced
consumed 0
2 produced
consumed 1
consumed 2
3 produced
consumed 34 produced
consumed 4
5 produced
consumed 5
6 produced
consumed 6
7 produced
consumed 7
8 produced
9 produced
consumed 8
consumed 9
使用 ConditonVariable进行同步控制,能够在一些致命的资源竞争部分挂起线程直到有可用的资源为止。
[ruby] view
plaincopy
#encoding:gbk
require "thread"
puts "thread synchronize by ConditionVariable"
mutex = Mutex.new
resource = ConditionVariable.new
a = Thread.new {
mutex.synchronize {
# 这个线程目前需要resource这个资源
resource.wait(mutex)
puts "get resource"
}
}
b = Thread.new {
mutex.synchronize {
#线程b完成对resourece资源的使用并释放resource
resource.signal
}
}
a.join
puts "complete"
mutex 是声明的一个资源,然后通过ConditionVariable来控制申请和释放这个资源。
b 线程完成了某些工作之后释放资源resource.signal,这样a线程就可以获得一个mutex资源然后进行执行。
执行结果:
[html] view
plaincopy
thread synchronize by ConditionVariable
get resource
complete
1. 通过Mutex类实现线程同步
2. 监管数据交接的Queue类实现线程同步
3. 使用ConditionVariable实现同步控制
1. 通过Mutex类实现线程同步
通过Mutex类实现线程同步控制,如果在多个线程钟同时需要一个程序变量,可以将这个变量部分使用lock锁定。代码如下:
[ruby] view
plaincopy
#encoding:gbk
require "thread"
puts "Synchronize Thread"
@num=200
@mutex=Mutex.new
def buyTicket(num)
@mutex.lock
if @num>=num
@num=@num-num
puts "you have successfully bought #{num} tickets"
else
puts "sorry,no enough tickets"
end
@mutex.unlock
end
ticket1=Thread.new 10 do
10.times do |value|
ticketNum=15
buyTicket(ticketNum)
sleep 0.01
end
end
ticket2=Thread.new 10 do
10.times do |value|
ticketNum=20
buyTicket(ticketNum)
sleep 0.01
end
end
sleep 1
ticket1.join
ticket2.join
程序运行的输出:
[ruby] view
plaincopy
Synchronize Thread
you have successfully bought 15 tickets
you have successfully bought 20 tickets
you have successfully bought 15 tickets
you have successfully bought 20 tickets
you have successfully bought 15 tickets
you have successfully bought 20 tickets
you have successfully bought 15 tickets
you have successfully bought 20 tickets
you have successfully bought 15 tickets
you have successfully bought 20 tickets
you have successfully bought 15 tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
除了使用lock锁定变量,还可以使用try_lock锁定变量,还可以使用Mutex.synchronize同步对某一个变量的访问。
2. 监管数据交接的Queue类实现线程同步
Queue类就是表示一个支持线程的队列,能够同步对队列末尾进行访问。不同的线程可以使用统一个对类,但是不用担心这个队列中的数据是否能够同步,另外使用SizedQueue类能够限制队列的长度SizedQueue类能够非常便捷的帮助我们开发线程同步的应用程序,应为只要加入到这个队列中,就不用关心线程的同步问题。
经典的生产者消费者问题:
[ruby] view
plaincopy
#encoding:gbk
require "thread"
puts "SizedQuee Test"
queue = Queue.new
producer = Thread.new do
10.times do |i|
sleep rand(i) # 让线程睡眠一段时间
queue << i
puts "#{i} produced"
end
end
consumer = Thread.new do
10.times do |i|
value = queue.pop
sleep rand(i/2)
puts "consumed #{value}"
end
end
consumer.join
程序的输出:
[ruby] view
plaincopy
SizedQuee Test
0 produced
1 produced
consumed 0
2 produced
consumed 1
consumed 2
3 produced
consumed 34 produced
consumed 4
5 produced
consumed 5
6 produced
consumed 6
7 produced
consumed 7
8 produced
9 produced
consumed 8
consumed 9
3. 使用ConditionVariable实现同步控制
使用 ConditonVariable进行同步控制,能够在一些致命的资源竞争部分挂起线程直到有可用的资源为止。[ruby] view
plaincopy
#encoding:gbk
require "thread"
puts "thread synchronize by ConditionVariable"
mutex = Mutex.new
resource = ConditionVariable.new
a = Thread.new {
mutex.synchronize {
# 这个线程目前需要resource这个资源
resource.wait(mutex)
puts "get resource"
}
}
b = Thread.new {
mutex.synchronize {
#线程b完成对resourece资源的使用并释放resource
resource.signal
}
}
a.join
puts "complete"
mutex 是声明的一个资源,然后通过ConditionVariable来控制申请和释放这个资源。
b 线程完成了某些工作之后释放资源resource.signal,这样a线程就可以获得一个mutex资源然后进行执行。
执行结果:
[html] view
plaincopy
thread synchronize by ConditionVariable
get resource
complete
相关文章推荐
- Ruby on Rails 入门之:(19) ruby线程同步控制
- Ruby on Rails 入门之:(18) ruby线程控制,线程同步
- Ruby on Rails 入门之:(20) ruby线程控制的join
- Ruby on Rails入门例子(Ruby1.8.6 gem 1.3.1 Rail 2.2.3)
- Ruby on rails 2.0.2傻瓜入门之Hello world
- Ruby on Rails 入门之:(22) Ruby 中Time的使用
- Ruby on Rails 入门 ----respond_to
- [Ruby On Rails] Action Controller - 控制HTTP 流程
- ruby on rails入门系列--ruby的基本语法
- DB2 与 Ruby on Rails,第 1 部分: DB2 与 Ruby on Rails 入门
- 通过Ruby on Rails和docker构建微服务架构之入门教程
- 利用Radrails开发Ruby on Rails程序入门指南
- ruby on rails入门笔记(1)-数据库迁移
- Ruby on Rails 入门之:(6) Ruby中常用运算符
- ruby on rails 入门
- Ruby on Rails 入门 ----respond_to
- Ruby on rails 实战圣经:Ruby程序语言入门
- Ruby on Rails 入门之:(26) Rails找不到数据库表解决办法 2
- ruby on rails 自学笔记 (1)入门篇
- [入门]Ruby on Rails入门教程及开发工具选用