Ruby on Rails 入门之:(18) ruby线程控制,线程同步
2012-10-10 11:56
639 查看
在Ruby中线程是用户级线程并依赖与操作系统。线程是进程中的一个实体,是被系统独立调度和分配的基本单位。线程可以与同属于同样个进程的其他线程共同共享进程的全部资源。但是线程不拥有资源,只需要一点在运行时必不可少的资源。
线程的基本控制,如果主进程结束,会结束所有的线程。所以如果你的线程在执行显示的任务,但是主进程却已经执行完毕,会看不到线程的任何输出。如链接中所示:
http://blog.csdn.net/weixingstudio/article/details/7796442
线程的创建可以使用Thread.new,同样可以以同样的语法使用Thread.start 或者Thread.fork这三个方法来创建线程。
创建线程并执行的基本代码:
[ruby] view
plaincopy
i=1
puts "hello thread"
puts Time.new
#round=5
#while i<round
# puts "the #{i}th round"
# i=i+1
#end
thread1=Thread.start 10 do |value|
while i<value
puts "#{i}"
i=i+1
end
end
thread1.join
thread2=Thread.start do
10.times do |a|
puts "the #{a+1} output"
end
end
thread2.join
上面的代码中,线程thread1线程创建以后,调用了thread1.join方法,这个方法会挂起主线程,等待thread1线程完成,这样就可一在主线程结束之前看到线程thread1,thread2的输出消息。
上面的线程的运行结果:
[ruby] view
plaincopy
1
2
3
4
5
6
7
8
9
the 1 output
the 2 output
the 3 output
the 4 output
the 5 output
the 6 output
the 7 output
the 8 output
the 9 output
the 10 output
但是这样可以看到,线程的输出是等到线程thread1完全执行完毕以后才执行线程thread2,有经验的朋友就会知道线程的调度是随机的,所以如果没有thread1.join和thread2.join两个方法,线程的输出就会变得没有规律,下面我们该一下程序看看没有规律的线程输出。
[ruby] view
plaincopy
i=1
puts "hello thread"
puts Time.new
#round=5
#while i<round
# puts "the #{i}th round"
# i=i+1
#end
thread1=Thread.start 10 do |value|
while i<value
puts "#{i}\n"
i=i+1
end
end
thread2=Thread.start do
10.times do |a|
puts "the #{a+1} output\n"
end
end
thread1.join
thread2.join
这样两个线程都开启以后,等调用join方法等待两个线程完成。
输出的结果:
[ruby] view
plaincopy
hello thread
2012-07-28 19:22:15 +0800
1
the 1 output
2
the 2 output
3
the 3 output
4
the 4 output
5
6
the 5 output
7
the 6 output
8
the 7 output
9
the 8 output
the 9 output
the 10 output
可以看到输出的结果已经变得没有规律了。
上面已经提到了,通过join方法可以等待指定的线程执行完毕。同时Ruby钟还有一种方法可以实现等待指定线程运行完毕,就是value方法,value方法还可以获得线程的值。
通过Thread.current方法可以获得线程的id。如下面的代码:
[ruby] view
plaincopy
#encoding:gbk
require "thread"
i=1
puts "hello thread"
puts Time.new
#round=5
#while i<round
# puts "the #{i}th round"
# i=i+1
#end
thread1=Thread.start 10 do |value|
while i<value
id=Thread.current
puts "#{i} 当前执行的线程id:#{id}\n"
i=i+1
end
end
thread2=Thread.start do
10.times do |a|
id=Thread.current
puts "the #{a+1} output 当前执行的线程id:#{id}\n"
end
end
thread1.join
thread2.join
这里想让Ruby输出中文的话,需要添加语句到文件头:
[ruby] view
plaincopy
#encoding:gbk
上面代码的执行结果:
[html] view
plaincopy
hello thread
2012-07-28 19:29:35 +0800
the 1 output 当前执行的线程id:#<Thread:0x87788e8>
the 2 output 当前执行的线程id:#<Thread:0x87788e8>
1 当前执行的线程id:#<Thread:0x8778924>
the 3 output 当前执行的线程id:#<Thread:0x87788e8>
2 当前执行的线程id:#<Thread:0x8778924>
the 4 output 当前执行的线程id:#<Thread:0x87788e8>
3 当前执行的线程id:#<Thread:0x8778924>
the 5 output 当前执行的线程id:#<Thread:0x87788e8>
4 当前执行的线程id:#<Thread:0x8778924>
the 6 output 当前执行的线程id:#<Thread:0x87788e8>
5 当前执行的线程id:#<Thread:0x8778924>
the 7 output 当前执行的线程id:#<Thread:0x87788e8>
6 当前执行的线程id:#<Thread:0x8778924>
the 8 output 当前执行的线程id:#<Thread:0x87788e8>
7 当前执行的线程id:#<Thread:0x8778924>
the 9 output 当前执行的线程id:#<Thread:0x87788e8>
8 当前执行的线程id:#<Thread:0x8778924>
the 10 output 当前执行的线程id:#<Thread:0x87788e8>
9 当前执行的线程id:#<Thread:0x8778924>
还是那个程序,稍加改动:
[ruby] view
plaincopy
i=1
puts "hello thread"
puts Time.new
#round=5
#while i<round
# puts "the #{i}th round"
# i=i+1
#end
thread1=Thread.start 10 do |value|
while i<value
puts "#{i} \n"
i=i+1
if i>5
Thread.exit
end
end
end
thread2=Thread.start do
10.times do |a|
puts "the #{a+1} output\n"
end
end
thread1.join
thread2.join
当thead1线程中i超过5以后,结束那个线程。
输出结果:
[html] view
plaincopy
hello thread
2012-07-28 19:39:42 +0800
1
the 1 output
2
the 2 output
3
the 3 output
4
the 4 output
5
the 5 output
the 6 output
the 7 output
the 8 output
the 9 output
the 10 output
同时线程的结束还可以使用Thread.exit。
使用sleep函数让线程休眠,对于同样的程序进行修改:
[ruby] view
plaincopy
i=1
puts "hello thread"
puts Time.new
#round=5
#while i<round
# puts "the #{i}th round"
# i=i+1
#end
thread1=Thread.start 10 do |value|
sleep 3
while i<value
puts "#{i} \n"
i=i+1
end
end
thread2=Thread.start do
10.times do |a|
puts "the #{a+1} output\n"
end
end
thread1.join
thread2.join
当线程thread1开启以后,休眠3秒钟,输出的结果:
[html] view
plaincopy
hello thread
2012-07-28 19:43:37 +0800
the 1 output
the 2 output
the 3 output
the 4 output
the 5 output
the 6 output
the 7 output
the 8 output
the 9 output
the 10 output
1
2
3
4
5
6
7
8
9
可以看到线程thread2的所有输出都完成之后,线程thread1才从睡眠中唤醒,而且中间等待了大概有三秒钟的时间。
线程的基本控制,如果主进程结束,会结束所有的线程。所以如果你的线程在执行显示的任务,但是主进程却已经执行完毕,会看不到线程的任何输出。如链接中所示:
http://blog.csdn.net/weixingstudio/article/details/7796442
线程的创建可以使用Thread.new,同样可以以同样的语法使用Thread.start 或者Thread.fork这三个方法来创建线程。
创建线程并执行的基本代码:
[ruby] view
plaincopy
i=1
puts "hello thread"
puts Time.new
#round=5
#while i<round
# puts "the #{i}th round"
# i=i+1
#end
thread1=Thread.start 10 do |value|
while i<value
puts "#{i}"
i=i+1
end
end
thread1.join
thread2=Thread.start do
10.times do |a|
puts "the #{a+1} output"
end
end
thread2.join
上面的代码中,线程thread1线程创建以后,调用了thread1.join方法,这个方法会挂起主线程,等待thread1线程完成,这样就可一在主线程结束之前看到线程thread1,thread2的输出消息。
上面的线程的运行结果:
[ruby] view
plaincopy
1
2
3
4
5
6
7
8
9
the 1 output
the 2 output
the 3 output
the 4 output
the 5 output
the 6 output
the 7 output
the 8 output
the 9 output
the 10 output
但是这样可以看到,线程的输出是等到线程thread1完全执行完毕以后才执行线程thread2,有经验的朋友就会知道线程的调度是随机的,所以如果没有thread1.join和thread2.join两个方法,线程的输出就会变得没有规律,下面我们该一下程序看看没有规律的线程输出。
[ruby] view
plaincopy
i=1
puts "hello thread"
puts Time.new
#round=5
#while i<round
# puts "the #{i}th round"
# i=i+1
#end
thread1=Thread.start 10 do |value|
while i<value
puts "#{i}\n"
i=i+1
end
end
thread2=Thread.start do
10.times do |a|
puts "the #{a+1} output\n"
end
end
thread1.join
thread2.join
这样两个线程都开启以后,等调用join方法等待两个线程完成。
输出的结果:
[ruby] view
plaincopy
hello thread
2012-07-28 19:22:15 +0800
1
the 1 output
2
the 2 output
3
the 3 output
4
the 4 output
5
6
the 5 output
7
the 6 output
8
the 7 output
9
the 8 output
the 9 output
the 10 output
可以看到输出的结果已经变得没有规律了。
挂起当前的线程
上面已经提到了,通过join方法可以等待指定的线程执行完毕。同时Ruby钟还有一种方法可以实现等待指定线程运行完毕,就是value方法,value方法还可以获得线程的值。通过Thread.current方法可以获得线程的id。如下面的代码:
[ruby] view
plaincopy
#encoding:gbk
require "thread"
i=1
puts "hello thread"
puts Time.new
#round=5
#while i<round
# puts "the #{i}th round"
# i=i+1
#end
thread1=Thread.start 10 do |value|
while i<value
id=Thread.current
puts "#{i} 当前执行的线程id:#{id}\n"
i=i+1
end
end
thread2=Thread.start do
10.times do |a|
id=Thread.current
puts "the #{a+1} output 当前执行的线程id:#{id}\n"
end
end
thread1.join
thread2.join
这里想让Ruby输出中文的话,需要添加语句到文件头:
[ruby] view
plaincopy
#encoding:gbk
上面代码的执行结果:
[html] view
plaincopy
hello thread
2012-07-28 19:29:35 +0800
the 1 output 当前执行的线程id:#<Thread:0x87788e8>
the 2 output 当前执行的线程id:#<Thread:0x87788e8>
1 当前执行的线程id:#<Thread:0x8778924>
the 3 output 当前执行的线程id:#<Thread:0x87788e8>
2 当前执行的线程id:#<Thread:0x8778924>
the 4 output 当前执行的线程id:#<Thread:0x87788e8>
3 当前执行的线程id:#<Thread:0x8778924>
the 5 output 当前执行的线程id:#<Thread:0x87788e8>
4 当前执行的线程id:#<Thread:0x8778924>
the 6 output 当前执行的线程id:#<Thread:0x87788e8>
5 当前执行的线程id:#<Thread:0x8778924>
the 7 output 当前执行的线程id:#<Thread:0x87788e8>
6 当前执行的线程id:#<Thread:0x8778924>
the 8 output 当前执行的线程id:#<Thread:0x87788e8>
7 当前执行的线程id:#<Thread:0x8778924>
the 9 output 当前执行的线程id:#<Thread:0x87788e8>
8 当前执行的线程id:#<Thread:0x8778924>
the 10 output 当前执行的线程id:#<Thread:0x87788e8>
9 当前执行的线程id:#<Thread:0x8778924>
线程的停止
可以使用Thread.pass停止当前线程。还是那个程序,稍加改动:
[ruby] view
plaincopy
i=1
puts "hello thread"
puts Time.new
#round=5
#while i<round
# puts "the #{i}th round"
# i=i+1
#end
thread1=Thread.start 10 do |value|
while i<value
puts "#{i} \n"
i=i+1
if i>5
Thread.exit
end
end
end
thread2=Thread.start do
10.times do |a|
puts "the #{a+1} output\n"
end
end
thread1.join
thread2.join
当thead1线程中i超过5以后,结束那个线程。
输出结果:
[html] view
plaincopy
hello thread
2012-07-28 19:39:42 +0800
1
the 1 output
2
the 2 output
3
the 3 output
4
the 4 output
5
the 5 output
the 6 output
the 7 output
the 8 output
the 9 output
the 10 output
同时线程的结束还可以使用Thread.exit。
使用sleep函数让线程休眠,对于同样的程序进行修改:
[ruby] view
plaincopy
i=1
puts "hello thread"
puts Time.new
#round=5
#while i<round
# puts "the #{i}th round"
# i=i+1
#end
thread1=Thread.start 10 do |value|
sleep 3
while i<value
puts "#{i} \n"
i=i+1
end
end
thread2=Thread.start do
10.times do |a|
puts "the #{a+1} output\n"
end
end
thread1.join
thread2.join
当线程thread1开启以后,休眠3秒钟,输出的结果:
[html] view
plaincopy
hello thread
2012-07-28 19:43:37 +0800
the 1 output
the 2 output
the 3 output
the 4 output
the 5 output
the 6 output
the 7 output
the 8 output
the 9 output
the 10 output
1
2
3
4
5
6
7
8
9
可以看到线程thread2的所有输出都完成之后,线程thread1才从睡眠中唤醒,而且中间等待了大概有三秒钟的时间。
相关文章推荐
- Ruby on Rails 入门之:(19) ruby线程同步控制
- Ruby on Rails 入门之:(19) ruby线程同步控制
- Ruby on Rails 入门之:(20) ruby线程控制的join
- Ruby on Rails 入门之:(17) 初次接触ruby线程
- Ruby on Rails教程 和Ruby&Rails 入门大全,对新手很有用(转)
- Ruby on Rails 入门之:(14) Ruby中的继承
- [入门]Ruby on Rails入门教程及开发工具选用
- Ruby on Rails入门(1)
- [入门]Ruby on Rails入门教程及开发工具选用
- Ruby on Rails入门篇
- [Ruby On Rails] Action Controller - 控制HTTP 流程
- ruby on rails 指导入门 http://ihower.tw/rails3/firststep.html
- 我整理的Ruby on Rails教程 和Ruby&Rails 入门大全,对新手很有用
- Ruby on rails开发从头来(windows)(十七)-控制访问权限
- Ruby on Rails研究之二:简单入门
- ruby on rails入门系列--ruby和rails的安装
- Ruby on Rails 入门级简介
- ruby on rails3 入门 ——尝鲜吧!骚年
- Ruby On Rails系列从入门到精通实战教程 Ruby基础教程下载
- [ROR] ruby on rails 入门知识