zoukankan      html  css  js  c++  java
  • Ruby 1

    使用Ruby可以写出简短而又功能强大的代码
    下面的方法用来完成两个矩阵的乘积

    def matrix_mul(matrix1,matrix2)
        result=[]
        (0...matrix1.length).each{|i|
            temp=[]
            (0...matrix2[0].length).each{|j|
                tmp=0
                (0...matrix1[0].length).each{|k|
                    tmp+=matrix1[i][k]*matrix2[k][j]
                }
                temp<<tmp
            }
            result<<temp
        }
        return result
    end
    

    注:ruby标准库中已包含矩阵库 Matrix

    Ruby 多线程

    # 线程 #1 代码部分
    Thread.new {
      # 线程 #2 执行代码
    }
    # 线程 #1 执行代码
    

    实例
    以下实例展示了如何在Ruby程序中使用多线程:

    #!/usr/bin/ruby
    
    def func1
       i=0
       while i<=2
          puts "func1 at: #{Time.now}"
          sleep(2)
          i=i+1
       end
    end
    
    def func2
       j=0
       while j<=2
          puts "func2 at: #{Time.now}"
          sleep(1)
          j=j+1
       end
    end
    
    puts "Started At #{Time.now}"
    t1=Thread.new{func1()}
    t2=Thread.new{func2()}
    t1.join
    t2.join
    puts "End at #{Time.now}"
    
    Started At Wed May 14 08:21:54 -0700 2014
    func1 at: Wed May 14 08:21:54 -0700 2014
    func2 at: Wed May 14 08:21:54 -0700 2014
    func2 at: Wed May 14 08:21:55 -0700 2014
    func1 at: Wed May 14 08:21:56 -0700 2014
    func2 at: Wed May 14 08:21:56 -0700 2014
    func1 at: Wed May 14 08:21:58 -0700 2014
    End at Wed May 14 08:22:00 -0700 2014
    

    线程状态
    线程有5种状态:

    线程状态 返回值
    Runnable run
    Sleeping Sleeping
    Aborting aborting
    Terminated normally false
    Terminated with exception nil
    begin
      t = Thread.new do
        Thread.pass    # 主线程确实在等join
        raise "unhandled exception"
      end
      t.join
    rescue
      p $!  # => "unhandled exception"
    end
    

    通过Mutex类实现线程同步
    通过Mutex类实现线程同步控制,如果在多个线程钟同时需要一个程序变量,可以将这个变量部分使用lock锁定。 代码如下:

    #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
    
    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同步对某一个变量的访问。


    监管数据交接的Queue类实现线程同步
    Queue类就是表示一个支持线程的队列,能够同步对队列末尾进行访问。不同的线程可以使用统一个对类,但是不用担心这个队列中的数据是否能够同步,另外使用SizedQueue类能够限制队列的长度
    SizedQueue类能够非常便捷的帮助我们开发线程同步的应用程序,应为只要加入到这个队列中,就不用关心线程的同步问题。
    经典的生产者消费者问题:

    #!/usr/bin/ruby
    
    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
    
    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
    
    #!/usr/bin/ruby
    
    count = 0
    arr = []
    
    10.times do |i|
       arr[i] = Thread.new {
          sleep(rand(0)/10.0)
          Thread.current["mycount"] = count
          count += 1
       }
    end
    
    arr.each {|t| t.join; print t["mycount"], ", " }
    puts "count = #{count}"
    
    8, 0, 3, 7, 2, 1, 6, 5, 4, 9, count = 10
    

    线程优先级
    线程的优先级是影响线程的调度的主要因素。其他因素包括占用CPU的执行时间长短,线程分组调度等等。

    可以使用 Thread.priority 方法得到线程的优先级和使用 Thread.priority= 方法来调整线程的优先级。

    线程的优先级默认为 0 。 优先级较高的执行的要快。

    一个 Thread 可以访问自己作用域内的所有数据,但如果有需要在某个线程内访问其他线程的数据应该怎么做呢? Thread 类提供了线程数据互相访问的方法,你可以简单的把一个线程作为一个 Hash 表,可以在任何线程内使用 []= 写入数据,使用 [] 读出数据。

    athr = Thread.new { Thread.current["name"] = "Thread A"; Thread.stop }
    bthr = Thread.new { Thread.current["name"] = "Thread B"; Thread.stop }
    cthr = Thread.new { Thread.current["name"] = "Thread C"; Thread.stop }
    Thread.list.each {|x| puts "#{x.inspect}: #{x["name"]}" }
    

    可以看到,把线程作为一个 Hash 表,使用 [] 和 []= 方法,我们实现了线程之间的数据共享。

    线程互斥
    Mutex(Mutal Exclusion = 互斥锁)是一种用于多线程编程中,防止两条线程同时对同一公共资源(比如全局变量)进行读写的机制。

    不使用Mutax的实例

    #!/usr/bin/ruby
    require 'thread'
    
    count1 = count2 = 0
    difference = 0
    counter = Thread.new do
       loop do
          count1 += 1
          count2 += 1
       end
    end
    spy = Thread.new do
       loop do
          difference += (count1 - count2).abs
       end
    end
    sleep 1
    puts "count1 :  #{count1}"
    puts "count2 :  #{count2}"
    puts "difference : #{difference}"
    
    count1 :  9712487
    count2 :  12501239
    difference : 0
    

    使用Mutax的实例

    #!/usr/bin/ruby
    require 'thread'
    mutex = Mutex.new
    
    count1 = count2 = 0
    difference = 0
    counter = Thread.new do
       loop do
          mutex.synchronize do
             count1 += 1
             count2 += 1
          end
        end
    end
    spy = Thread.new do
       loop do
           mutex.synchronize do
              difference += (count1 - count2).abs
           end
       end
    end
    sleep 1
    mutex.lock
    puts "count1 :  #{count1}"
    puts "count2 :  #{count2}"
    puts "difference : #{difference}"
    
    count1 :  1336406
    count2 :  1336406
    difference : 0
    

    死锁
    两个以上的运算单元,双方都在等待对方停止运行,以获取系统资源,但是没有一方提前退出时,这种状况,就称为死锁。

    例如,一个进程 p1占用了显示器,同时又必须使用打印机,而打印机被进程p2占用,p2又必须使用显示器,这样就形成了死锁。

    当我们在使用 Mutex 对象时需要注意线程死锁。

    #!/usr/bin/ruby
    require 'thread'
    mutex = Mutex.new
    
    cv = ConditionVariable.new
    a = Thread.new {
       mutex.synchronize {
          puts "A: I have critical section, but will wait for cv"
          cv.wait(mutex)
          puts "A: I have critical section again! I rule!"
       }
    }
    
    puts "(Later, back at the ranch...)"
    
    b = Thread.new {
       mutex.synchronize {
          puts "B: Now I am critical, but am done with cv"
          cv.signal
          puts "B: I am still critical, finishing up"
       }
    }
    a.join
    b.join
    

    其他笔记

  • 相关阅读:
    Day1-while and for/break and continue
    Day1-用户输入及字符串格式化输入
    Day1-python基础
    2-21-源码编译搭建LNMP环境
    2-20-使用apache搭建web网站
    2-19-mysql优化
    2-18-搭建mysql集群实现高可用
    2-17-MySQL读写分离-mysql-proxy
    2-16-2MySQL主从
    2-14-存储过程-触发器-事务
  • 原文地址:https://www.cnblogs.com/ukzq/p/13375918.html
Copyright © 2011-2022 走看看