Initial introduction to Ruby multithreaded programming

Source: Internet
Author: User
Tags abs instance method join mutex require sleep thread class

This article mainly introduces the initial introduction of Ruby multithreaded programming, thread is the focus of Ruby programming learning and difficult, the need for friends can refer to the

A traditional program has a separate thread that executes the statement or instruction sequence that contains the program until the program terminates.

A multithreaded program has multiple threads executing. Each thread is executed sequentially, but the multiple-core CPU machine thread may execute in parallel. For example, in the case of a single CPU machine, multiple threads are not actually executing in parallel, but rather simulating the execution of threads that intersect in parallel.

Ruby can easily write multithreaded programs using the Thread class. Ruby threads are a lightweight and efficient implementation of parallelism in your code.

To create a ruby thread:

To start a new thread, associate a block by calling Thread.new. A new thread execution code block will be created, and the original thread will immediately return from thread.new and continue execution of the next statement:

?

1 2 3 4 5 # thread #1 is running thread.new {# thread #2 runs this code} # thread #1 runs this code

For example:

Here is an example of how we can take advantage of multithreaded ruby programs.

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 The 25 26 #!/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& Lt;=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}"

This will produce the following results:

?

1 2 3 4 5 6 7 8 started at Wed could 08:21:54-0700 2008 func1 at:wed May 08:21:54-0700 2008 Func2 at:wed May 14 08:21:54-0700 200 8 Func2 at:wed May 08:21:55-0700 2008 Func1 at:wed could 08:21:56-0700 2008 Func2 at:wed May 14 08:21:56-0700 20 Func1 at:wed May 08:21:58-0700 2008 end in Wed May 14 08:22:00-0700 2008

Life cycle of Threads:

Create a new thread with the thread.new. Synonyms can also be used with Thread.Start and thread.fork.

It is not necessary to start a thread when it is created, it will automatically start running when CPU resources become available.

The thread class defines methods to query and process threads at run time. Run the code in a thread block to call Thread.new, and then it stops running.

The value of the last expression in the block is the value of the thread, which can be invoked by calling the method of the thread object value. If the thread runs complete, the value is the return value of the thread. Otherwise, the value method blocks and does not return until the thread has completed.

The class method thread.current returns a Thread object that represents the current thread. This allows the thread to manipulate itself. The class method Thread.main returns the thread object to represent the main thread, thread.this the initial thread starts executing the Ruby program.

You can wait for a particular thread to complete by calling the thread's Thread.Join method. The calling thread will be blocked until the given thread completes.

Threads and Exceptions:

If an exception is thrown in the main thread and there is no place to handle it, the Ruby interpreter prints a message and exits. In other threads other than the main thread, unhandled exceptions cause the thread to stop running.

If the thread t exits because of an unhandled exception and another thread calls T.join or T.value, then the exception that occurred in T is the thread s.

If Thread.abort_on_exception is false, by default, an unhandled exception kills only the current thread and all the rest continues to run.

The Set class method Thread.abort_on_exception is True if you want any unhandled exception in any thread to cause an explanation to exit.

?

1 2 t = thread.new {...} t.abort_on_exception = True

Thread variables:

A thread can normally be accessed when a thread of any variable within the scope is created. A local variable of a thread block is part of the thread, not a share.

The thread class provides a special feature that allows you to create and access thread-local variables by name. Simply put the thread object, if it is a hash, write the element using [] = and read them back with the use [].

In this example, each thread records the current value of the count variable with a threadlocal variable mycount the key.

?

1 2 3 4, 5 6 7 8 9 10 11 12 13 14 15 #!/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}"

This will produce the following results:

?

1 8, 0, 3, 7, 2, 1, 6, 5, 4, 9, Count = 10

The main thread waits for the child thread to complete, and then prints out the value of each captured count.

Thread Priority:

The first factor that affects thread scheduling is the priority of a thread: a low-priority thread that was planned before a high-priority thread. Rather, a thread will only get CPU time if no higher priority thread is waiting to run.

You can set and query the priority = and priority of a Ruby thread object. The newly created thread starts to create it at the same priority thread. Start primary thread priority is 0.

There is no way to set the thread priority before it starts running. However, a thread can raise or lower its own priority for the first operation.

Thread repulsion:

If two threads share access to the same data, and at least one thread modifies the data, you must be particularly careful to ensure that no thread can see the data in an inconsistent state. This is called thread exclusion.

Mutex classes are mutually exclusive access to some shared resources and implement a simple signal lock. That is, only one thread can hold a lock at a given time. Other threads may choose to have a queued lock become available, or you can simply choose to get an error immediately, indicating that the lock is not available.

By controlling all the mutexes that access the shared data, we ensure consistency and atomic operations. Our trial example, the first one without Mutax, the second one uses mutax:

No mutax examples are required:

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19-20 #!/usr/bin/ruby require ' thread ' count1 = Count2 = 0 Difference = 0 Counter = Thread.new Do loop do count1 = 1 Count2 + = 1 End spy = Thread.new doing loop do difference + = (count1-count2). Abs End sleep 1 puts "count1: #{count1}" puts ' Count2: #{count2} ' puts ' difference: #{difference} '

This will produce the following results:

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 count1:1583766 count2:1583766 difference:637992 #!/usr/bin/ruby require ' thread ' mutex = mutex.new count1 = Coun T2 = 0 Difference = 0 Counter = Thread.new Do loop does mutex.synchronize do count1 = 1 Count2 + + 1 End-end spy = Threa D.new Do Loop did mutex.synchronize do difference + = (count1-count2). ABS End end sleep 1 Mutex.lock puts "count1: #{ COUNT1} "puts" Count2: #{count2} "puts" difference: #{difference} "

This will produce the following results:

?

1 2 3 count1:696591 count2:696591 difference:0

Handling Deadlocks:

When we start using the thread exclusion of mutexes, we have to be careful to avoid deadlocks. When a deadlock occurs, all threads are waiting to acquire resources held by another thread. Because all threads are blocked, they cannot release the locks they hold. Because they can not release the lock, other threads cannot obtain these locks.

A condition variable is simply a signal that is associated with a resource and is used within the protection of a particular mutex. When a resource is not available, wait for a condition variable. This action frees up the corresponding mutex lock. When some other thread sends a signal to the resource that is available, the original thread waits and restores the critical section on the lock at the same time.

Example:

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23-24 #!/usr/bin/ruby require ' thread ' mutex = mutex.new CV = conditionvariable.new A = thread.new {mutex.synchronize {puts "A:I have critical section, but'll 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 critic Al, finishing Up "}} a.join B.join

This will produce the following results:

?

1 2 3 4 5 A:I have critical section, but'll wait for CV (later, back at the ranch ...) B:now I am Critical, but am done with CV b:i am still critical, finishing up A:I have critical section again! I rule!

Thread State:

There are five possible return values that correspond to the 5 possible states shown in the following table. The thread state returned by the State method.

Methods of the Thread class:

The thread class provides the following methods, which apply to all threads of the program. These methods are invoked using the name of the thread class, as follows:

?

1 Thread.abort_on_exception = True

Here is a complete list of all class methods:

Thread instance method:

These methods apply to one instance of a thread. These methods will be invoked, using an instance of one thread as follows:

?

1 2 3 4 5 6 7 #!/usr/bin/ruby thr = thread.new do # Calling a class method new puts ' in second Thread ' raise ' raise exception ' end THR . Join # Calling an instance method join

Here is a complete list of all instance methods:

Related Article

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

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.