From: shevegen@... Date: 2016-04-20T06:09:12+00:00 Subject: [ruby-core:75041] [Ruby trunk Bug#12298] Indeterministic ruby behavior when another thread is killed Issue #12298 has been updated by Robert A. Heiler. Hmm. Although the report was already rejected, and even if we all may agree that the honeybadger code was not brilliant, I feel that the overall issue here in regards to Threads may be useful for more people in the future too. For instance, without the blog explanation, where else would you find that much information about ruby code used for "real"? From the official documentation of Threads? http://ruby-doc.org/core-2.3.0/Thread.html The documentation is not bad at all, mind you, but the blog semi-taught me more than the documentation would. There may also be small improvements. We have instance methods like: "See also the instance methods alive? and stop?" In the code he checked whether the thread was aborting: Thread.current.status == "aborting" This could be simplified if the ruby code would allow for this check: Thread.current.aborting? Or perhaps even Thread.aborting? (I do not really know Threads that well that I can suggest an API that makes sense / is logical.) Without that block, I would probably have never been able to figure out that a thread is not just alive or dead but may be in between the two like the schroedinger cat. ---------------------------------------- Bug #12298: Indeterministic ruby behavior when another thread is killed https://bugs.ruby-lang.org/issues/12298#change-58166 * Author: Robert Pankowecki * Status: Rejected * Priority: Normal * Assignee: * ruby -v: ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux] * Backport: 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN ---------------------------------------- ``` #!ruby require 'securerandom' class MyThread < ::Thread; end def delay 15 end def run loop { work } rescue Exception => e puts "#{Time.now} Exception" ensure puts "#{Time.now} stopping agent" end def work puts "#{Time.now} start work" 10_000_000.times { SecureRandom.hex } puts "finished work" rescue StandardError => e puts "#{Time.now} Error" ensure puts "#{Time.now} start sleep" sleep(delay) puts "#{Time.now} finished sleep" end t = MyThread.new{ run } at_exit do puts "#{Time.now} killing thread" Thread.kill(t) puts "#{Time.now} killed thread" end sleep(10) exit ``` I tried running this script multiple times in ruby 2.1.10, 2.2.4, 2.3.0 and I get inconsistent behavior. Sometimes the main thread does not wait for the second thread. ``` 2016-04-15 11:07:09 +0200 start work 2016-04-15 11:07:19 +0200 killing thread 2016-04-15 11:07:19 +0200 killed thread 2016-04-15 11:07:19 +0200 stopping agent ``` And sometimes it does. ``` 2016-04-15 11:07:26 +0200 start work 2016-04-15 11:07:36 +0200 killing thread 2016-04-15 11:07:36 +0200 killed thread 2016-04-15 11:07:36 +0200 start sleep 2016-04-15 11:07:51 +0200 finished sleep 2016-04-15 11:07:51 +0200 stopping agent ``` I appears that under higher CPU usage the 2nd scenario is more likely. In normal conditions the 1st happens more often probably. I described [the whole story in my blogpost](http://blog.arkency.com/2016/04/how-i-hunted-the-most-odd-ruby-bug/) I am not sure which behavior is ruby default (I assume not waiting for other threads) but sometimes apparently ruby does wait for other threads to finish. ---Files-------------------------------- a.txt (3.09 KB) b.txt (3.58 KB) 12998.rb (508 Bytes) -- https://bugs.ruby-lang.org/ Unsubscribe: