您的位置:首页 > 编程语言 > Ruby

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>  

线程的停止

可以使用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才从睡眠中唤醒,而且中间等待了大概有三秒钟的时间。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息