A preliminary discussion on multithreading _ruby topics in Ruby programming

Source: Internet
Author: User
Tags mutex rand thread class

Each program that is running on the system is a process. Each process contains one or more threads.

A thread is a single sequential control process in a program that runs multiple threads at the same time in a single program to accomplish different tasks, called multithreading.

In Ruby, we can create multiple threads through the thread class, and Ruby threads are lightweight and can be implemented in parallel code in an efficient way.
Creating a Ruby thread

To start a new thread, you only need to invoke Thread.new:

# thread #1 Code part
thread.new {
 # thread #2 execute code
}
# thread #1 execute code

Instance

The following examples show how to use multithreading in a Ruby program:

#!/usr/bin/ruby
 
def func1
  i=0 while
  i<=2
   puts ' func1 at: #{time.now} ' sleep
   (2)
   i=i+ 1 End-
 
def func2
  j=0 while
  j<=2
   puts ' Func2 at: #{time.now} ' sleep
   (1)
   j=j+1
  End
 
puts ' started at #{time.now} '
t1=thread.new{func1 ()}
t2=thread.new{ Func2 ()}
t1.join
t2.join
puts "end at #{time.now}"

The above code execution results are:

started at Wed could 08:21:54-0700 2014 func1 at:wed May 08:21:54-0700 2014 Func2 at:wed may
14 08:21:54- 0700 2014
FUNC2 at:wed May 08:21:55-0700 2014 func1 at:wed May 08:21:56-0700 2014 Func2 at:wed
08:21:56-0700 2014
func1 at:wed May 08:21:58-0700 2014 end at
Wed May 14 08:22:00-0700 2014

Thread life cycle

1. Threads can be created using thread.new, as well as using Thread.Start or thread.fork these three methods to create threads in the same syntax.

2, the thread is automatically executed when the thread is created without starting.

3. The thread class defines methods to manipulate threads. The thread executes the code block in the Thread.new.

4. The last statement in the thread code block is the value of the thread, which can be invoked by means of a thread, and if the thread completes, the thread value is returned, otherwise the value is not returned until the thread has finished executing.

5. The Thread.current method returns the object representing the current thread. The Thread.main method returns the main thread.

6, through the Thread.Join method to execute the thread, this method will suspend the main thread until the current thread execution completed.
Thread State

There are 5 states of threads:

Threads and exceptions

When a thread has an exception and is not captured by rescue, the thread is usually terminated without warning. However, if there are other threads waiting for the thread because of the thread#join relationship, the waiting thread will also throw the same exception.

Begin
 T = thread.new
  do thread.pass  # main thread does wait for join
  raise "Unhandled exception"
 End
 T.join
rescue
 P $! # => "Unhandled exception"
end

Using the following 3 methods, you can have the interpreter break when a thread terminates because of an exception.

    • Specifies the-d option when you start the script and runs when you debug the mode.
    • Set the flag with Thread.abort_on_exception.
    • Sets a flag for the specified thread using Thread#abort_on_exception.

When one of these 3 methods is used, the entire interpreter is interrupted.

t = thread.new {...}
T.abort_on_exception = True

Thread Synchronization Control

In Ruby, there are three ways to implement synchronization, respectively:

1. Implement thread synchronization through mutex classes

2. The queue class for monitoring data handover implements thread synchronization

3. Use conditionvariable to realize synchronous control
Thread synchronization through a mutex class

Thread synchronization control is implemented through the mutex class, and if you need a program variable at the same time for multiple line Chengzhong, you can lock the variable part with lock. The code is as follows:

#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
 
Thread.new do
  10.times do |value|
  Ticketnum=15
  Buyticket (ticketnum) sleep
  0.01
  end
 
ticket2=thread.new
  10. Times do |value|
  Ticketnum=20
  Buyticket (ticketnum) sleep 0.01 End sleep
 
1
ticket1.join
Ticket2.join

The output results are as follows:

Synchronize Thread your have successfully bought tickets you have successfully bought to
tickets you
have SU Ccessfully bought have successfully bought tickets you have successfully bought tickets
y OU have successfully bought tickets you have successfully bought tickets you have successfully bought
Kets have successfully bought tickets you have successfully bought a
tickets you
have successfully b Ought 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

In addition to locking a variable with lock, you can also use Try_lock to lock a variable, and you can use Mutex.synchronize to synchronize access to a variable.
the queue class that regulates data handover implements thread synchronization

The queue class is the one that represents a support thread and is able to synchronize access to the end of the queue. Different threads can use a unified pair of classes, but don't worry about whether the data in this queue can be synchronized, and use the Sizedqueue class to limit the length of the queue

The Sizedqueue class can be very handy to help us develop thread-synchronized applications, so you don't have to worry about thread synchronization as long as you join this queue.

The classic producer consumer problem:

#encoding: GBK
require "thread"
puts "Sizedquee Test"
 
queue = queue.new producer
 
= Thread.new
  do 10.times do |i|
    Sleep rand (i) # get the thread sleeping for a period of time
    queue << i
    puts "#{i} produced" End end
 
consumer = thread.new do< C12/>10.times do |i|
    Value = Queue.pop sleep
    rand (I/2)
    puts ' consumed #{value} ' end end
 
consumer.join

Program output:
sizedquee Test
0 produced
1 produced
consumed 0
2 produced
consumed 1
Consumed 2
3 produced
consumed produced
 
consumed 4
5 produced
consumed 5
6 produced< C33/>consumed 6
7 produced
consumed 7
8 produced
9 produced
consumed 8
consumed 9

Using conditionvariable to implement synchronous control

Using conditonvariable for synchronous control, you can suspend threads until there is a resource available in some of the most lethal resource competition parts.

#encoding: GBK
require "thread"
puts "thread synchronize by conditionvariable"
 
mutex = mutex.new
Resource = conditionvariable.new
 
a = thread.new {
  mutex.synchronize {
    # This thread currently needs to resource this resource
    Resource.wait (mutex)
    puts "Get Resource"
  }
}
 
B = thread.new {
  mutex.synchronize {
    # Thread B completes the use of the Resourece resource and releases resource
    resource.signal
  }
}
 
a.join
puts "complete"

A mutex is a declared resource and is then controlled by Conditionvariable to request and release the resource.

The b thread frees the resource resource.signal after some work has been done, so that a thread can obtain a mutex resource and execute it. Execution results:

Thread synchronize by Conditionvariable get
resource
complete

Thread class methods

The complete thread (thread) class method is as follows:


Thread Instantiation Method

The following instance invokes the thread instantiation method join:

#!/usr/bin/ruby
 
thr = thread.new do  # instantiation
  puts ' in second Thread '
  raise ' raise exception '
end Thr.join  # Invokes the instantiation method join

The following is a list of the full instantiation methods:

Thread Instantiation Method

The following instance invokes the thread instantiation method join:

#!/usr/bin/ruby
 
thr = thread.new do  # instantiated
  puts "in second Thread"
  raise "
raise Exception" end< C16/>thr.join  # Invokes the instantiation method join

The following is a list of the full instantiation methods:


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.