熟悉线程的朋友应该对经典的售票员卖票程序不陌生。全国各地有很多售票点同时发售车票,车票在这里作为一个公用的资源,各地的售票中心访问资源,打印车票给顾客。我们来看一下ruby实现这个简单功能的代码吧:
# 线程-买票实例
class Ticket
attr_reader :ticket
attr_reader :value
def initialize
@ticket = %w(a b c d e f g h i j k l m n o p q r s t u v w x y z)
@value = 0
end
def buy_ticket
@k = @ticket
if @k.empty?
puts "no result"
@value +=1
else
sleep(3*rand)
puts "the ticket is #{@k.last} "
sleep(3*rand)
@value +=1
puts "OK #{@value}"
@ticket.pop
puts "**************分隔符******************"
end
end
end
a = Ticket.new
t1 = Thread.new { 10.times {puts "线程1" ; a.buy_ticket } }
t2 = Thread.new { 10.times { puts "线程2"; a.buy_ticket } }
t3 = Thread.new { 10.times { puts "线程3"; a.buy_ticket } }
t1.join
t2.join
t3.join
我们开了3个线程分别表示不同的3个售票点同事发售车票,我们在发售车票的时候使用了sleep来模拟工作人员操作的时间。
@ticket = %w(a b c d e f g h i j k l m n o p q r s t u v w x y z)
@ticket这个数组用来表示一组车票。好我们来运行这个程序,看能看到什么结果
线程1线程2线程3
the ticket is z
OK 1
**************分隔符******************
线程3
the ticket is y
the ticket is y
the ticket is y
OK 2
**************分隔符******************
线程2
OK 3
**************分隔符******************
线程1
OK 4
**************分隔符******************
线程3
the ticket is v
the ticket is v
the ticket is v
OK 5
我们可以看见,有的车票被多个窗口同时卖出,当然这在规定当中是不允许的。这个是为什么呢?我们来看一下程序。乍一看是肯定没有什么问题的。细细想想,假设我们的线程1进入卖票程序,并查看到当前可以买y票。线程1睡眠一段时间,假设这段时间正好线程2进来了,并执行了卖票程序,此时线程1并未实际意义上的把票卖了出去,这就导致了两个线程卖出了同一张票。
那么有没有解决办法呢?比如说,在线程1进入程序的时候,就把票给锁死了,这样线程2来的时候就不能对该张票进行操作。在ruby当中有个监视器monitor可是实现该功能。我们对买票这个操作进行监视控制,只能同时一个人来操作。好吧,我们来看一下下面的代码:
# 线程-买票实例
require 'monitor'
class Ticket
attr_reader :ticket
attr_reader :value
def initialize
@ticket = %w(a b c d e f g h i j k l m n o p q r s t u v w x y z)
@value = 0
end
def buy_ticket
@k = @ticket
if @k.empty?
puts "no result"
@value +=1
else
sleep(3*rand)
puts "the ticket is #{@k.last} "
sleep(3*rand)
@value +=1
puts "OK #{@value}"
@ticket.pop
puts "**************分隔符******************"
end
end
end
a = Ticket.new
k = Monitor.new
t1 = Thread.new { 10.times {k.synchronize{puts "线程1" ; a.buy_ticket }} }
t2 = Thread.new { 10.times {k.synchronize{puts "线程2" ; a.buy_ticket }} }
t3 = Thread.new { 10.times {k.synchronize{puts "线程3" ; a.buy_ticket }} }
t1.join
t2.join
t3.join
puts a.value
我们使用了监视器来对资源进行监视,不能同时由多个线程进行操作,避免重复卖票的情况,这中间的核心部分就是如下所示:
k = Monitor.new
t1 = Thread.new { 10.times {k.synchronize{puts "线程1" ; a.buy_ticket }} }
t2 = Thread.new { 10.times {k.synchronize{puts "线程2" ; a.buy_ticket }} }
t3 = Thread.new { 10.times {k.synchronize{puts "线程3" ; a.buy_ticket }} }
当然,我们可以不对该操作进行监视,我们对票据资源进行监视。也会使用到synchronize。这里就不再赘述,想知道的可以参考programming ruby。
好拉。今天就写这么多吧。o(∩_∩)o...哈哈
分享到:
相关推荐
这意味着即使在多核处理器上,Ruby线程也不能实现真正的并行执行。然而,通过合理的设计和使用外部库(如多进程、Fiber等),仍然可以在Ruby中实现高性能的并发程序。 #### 四、示例代码分析 以下是一个简单的Ruby...
### Ruby线程开发技术详解 #### 引言 在计算机科学领域中,多线程编程是一种常见的技术,它允许多个任务同时运行在一个程序中。《Working with Ruby Threads》这本书深入探讨了Ruby语言中的线程机制,对于希望利用...
ruby|线程生命周期及其状态
Ruby 中我们可以通过 Thread 类来创建多线程,Ruby的线程是一个轻量级的,可以以高效的方式来实现并行的代码。 创建 Ruby 线程 要启动一个新的线程,只需要调用 Thread.new 即可: # 线程 #1 代码部分 Thread.new {...
Ruby线程实现经典的生产者消费者问题,用ruby中的Queue类实现线程同步问题。 代码如下:require “thread” puts “ProAndCon” queue = Queue.new #用队列Queue实现线程同步 producer = Thread.new do 10....
"Working With Ruby Threads"这本书全面深入地探讨了这个主题,提供了关于Ruby线程的详尽知识。 在Ruby中,线程允许程序同时执行多个任务,从而提高了效率。Ruby的线程模型基于两种主要实现:MRI(Matz's Ruby ...
Goliath 是一个开源的非堵塞(异步) 的 Ruby Web 服务器框架,由 PostRank 开发。它是一个轻量级的框架提供高性能、Rack API 和中间件支持,配置简单,完全异步处理。 示例代码: require 'goliath' class ...
### 线程与并发:Ruby并行世界的探索之旅 #### Ruby 语言概览 Ruby 是一种高级的、面向对象的编程语言,由日本开发者松本行弘(Yukihiro "Matz" Matsumoto)于 1995 年创建。其设计初衷旨在实现简单、自然且强大的...
《Programming Ruby中文版第二版》是一本专注于Ruby编程语言的权威指南,对于想要深入学习和理解Ruby编程的读者来说,是一本不可多得的资源。Ruby作为一种动态、面向对象的编程语言,以其简洁、优雅的语法和强大的元...
多线程与并行程序设计是现代编程中的关键技术点,它们允许程序同时执行多个任务,提高程序的执行效率和响应速度。在Java中,这一技术通过内置的多线程支持得以实现,而线程作为执行任务的基本单位,是程序多任务运行...
4. **线程局部变量**:Ruby 3.1增加了对线程局部变量的支持,这些变量在每个线程中都有独立的副本,提高了多线程编程的安全性和效率。 5. **改进的错误消息**:错误消息现在更加详细,包含更多信息,帮助开发者更快...
JRuby的最大优点是与Java库的无缝集成,以及在多线程环境下的高效执行。 3. Rubinius:Rubinius是一个用Ruby语言大部分实现的虚拟机,其目标是提供一个高性能的、符合Ruby语言规范的平台。它使用LLVM作为后端,支持...
`Concurrent Ruby`的线程池实现了动态调整线程数量、任务调度和线程回收等功能,从而提高系统的资源利用率。使用线程池可以避免频繁地创建和销毁线程带来的开销,同时保证系统在高负载下的稳定性。 四、Supervisors...
3. **线程并行性增强**:Ruby 2.6加强了线程管理,允许在多核处理器上实现更好的并发性能,通过改进GVL(全局解释器锁)的实现,减少了线程之间的同步开销。 4. **安全的数组和哈希迭代**:为了防止某些类型的安全...
1. **Ruby内部机制揭秘**:每章末尾都包含“Digging Deeper”部分,揭示Ruby运行时的各种细节,如作用域解析、多线程实现等,帮助读者更好地理解语言本身的设计理念。 2. **陷阱与注意事项**:通过实际案例分析常见...
Ruby-Puma是一个高性能、轻量级且并发的Web服务器,专为Ruby编程语言设计。它在Ruby社区中广泛用于构建Web应用程序,特别是与Rails框架一起使用。Puma的设计目标是提供稳定、快速和易于管理的服务,同时保持低内存...
二、Ruby-Async框架 1. **协程(Coroutines)**:Ruby-Async的核心是基于协程的,这是一种轻量级的线程,可以在单个线程内实现并发。协程间的切换是用户级别的,比系统级别的线程调度更高效。通过`async`和`await`...
这在处理大量并发请求时特别有用,避免了线程或进程阻塞导致的资源浪费。 “可配置的负载平衡”意味着驱动程序允许开发者根据需求调整数据请求的分发方式,以优化整个系统的性能。这可能包括将请求分散到不同的节点...