I am trying to code up a two-threads client using ruby, one thread reads the data from a socket and print it out, the other thread reads local data and send it to remote server. The problem I found is that it looks like Ruby cannot capture errors within a thread, here is an example:
#! /usr/bin/ruby
Thread.new {
loop {
$stdout.puts "hi"
abc.puts ef
sleep 1
}
}
loop {
sleep 1
}
Obviously, outside the thread if I type abc.puts ef
the code will never run since Ruby will report "undefined variable abc". However if it is within a thread, there is no error report. My question is, how to let Ruby capture errors like this? Or at least, report something is wrong within a thread?
Multithreading is the ability to execute code on multiple concurrent threads. Each thread exists within a process, and each process can have at least one thread.
Thread in Ruby allows the developer to write codes where they can be able to write and execute many programs at once, in technical words suppose we are going to perform two operations addition and multiplication at the same time, it is not possible with normal way because it will execute either addition first or ...
Unfortunately, Ruby doesn't ship with any thread-safe Array or Hash implementations. The core Array and Hash classes are not thread-safe by default, nor should they be.
Only one thread may load or unload at a time, and to do either, it must wait until no other threads are running application code.
Use Thread::abort_on_exception=:
According to Thread - Exception Handling:
Any thread can raise an exception using the raise instance method, which operates similarly to Kernel#raise.
However, it's important to note that an exception that occurs in any thread except the main thread depends on abort_on_exception. This option is false by default, meaning that any unhandled exception will cause the thread to terminate silently when waited on by either join or value. You can change this default by either abort_on_exception= true or setting $DEBUG to true.
...
Thread::abort_on_exception = true
Thread.new {
loop {
$stdout.puts "hi"
abc.puts ef
sleep 1
}
}
loop {
sleep 1
}
=>
hi
t.rb:5:in `block (2 levels) in <main>': undefined local variable or method `abc' for main:Object (NameError)
from t.rb:3:in `loop'
from t.rb:3:in `block in <main>'
For syntax error catching, rescue must use explict Exception class (without this, rescue catch only StandardError) :
Thread.new {
begin
abc.puts ef
rescue Exception => e
puts "error #{e}"
end
}
see Why can't `rescue` catch exception classes other than `StandardError` by default?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With