Ruby线程学习(一)

      我们都知道,一个程序可能有多个进程组成,而一个进程也可以有多个线程并行运行。线程的并行运行,可以提高程序的运行效率,但也存在着很多的危险,可能出现多个线程抢占一个资源的情况。这里我们就以ruby为例来说一说线程在ruby当中的应用。

      我们先从一个简单的程序开始,程序实现一个并行对不同网站发送请求的过程。代码如下所示:

require 'net/http'

pages = %w(www.iteye.com www.csdn.net www.sina.com.cn www.google.cn)
threads = []

for page in pages
  threads << Thread.new(page) do |url|
    h = Net::HTTP.new(url, 80)
    puts "The URL is #{url} "
    resp = h.get('/', nil)
    puts "The #{url} response : #{resp.message}"
  end
end

threads.each { |t|t.join  }

      该段程序引用自Programming Ruby当中,程序中提供了一个网站列表数组,然后并发的从数组当中请求相应的网站。可能有些人对%w有些迷惑,%w会自动的对括号后面的字符串以空格进行分割,保存在数组当中。怎么样,ruby很sex吧,省去了很多的“”的困扰了。

      我们通过Thread.new来创建线程。我们将网站列表当中的地址作为参数传递给线程。这里有个问题就是我们为什么不把地址直接传递给block(net)呢。这里就牵扯到了线程的全局变量和局部变量的概念了。试想一下,如果我们把地址直接传递给net模块,那么如果在线程1没有执行完成的时候,线程2启动了,重新给page赋值,此时的线程1还在使用page。错误这个时候就会产生了,往往这种错误在线程并行当中很难发现。我们所做的就是将变量私有化给线程。这里我们将每个传递给线程的变量私有化未url,只在当前线程当中有效。这样就很好的解决了线程之间的一个全局变量共享的问题。

threads.each { |t|t.join  }

      大家可能注意到这段代码了,在ruby当中,当程序终止的时候,不管线程状态如何,所有的线程都会被杀死。我们调用Thread#join方法用来等待特定的线程结束。调用join的线程会阻塞,直到指定线程结束,所以对所有线程执行join操作,可以保证在程序结束前执行完所有的线程。


      上面提到了,线程可以有其私有变量,线程的私有变量在线程创建的时候写入线程。可以被线程范围内使用,但是不能被线程外部进行共享。但是有时候,线程的局部变量需要别别的线程或者主线程访问怎么办?ruby当中提供了允许通过名字来创建线程变量,类似的把线程看做hash式的散列表。通过[]=写入并通过[]读出数据。我们来看一下下面的代码:

# 线程变量

count = 0
threads =[]
10.times do |i|
  threads[i] = Thread.new  do
    sleep(rand(0.1))
    Thread.current["myvalue"] =count  #将值赋给当前变量
    count += 1
  end
end

threads.each { |t| t.join; puts t["myvalue"] }
  我们和前面的程序一样,分别创建10个线程,并将值赋值给当前线程,用myvalue进行标识,最后我们在线程外部可以通过myvalue标示对数据进行读取。 好吧,线程的第一步就说到这里把。明天继续
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值