1

Windows のシグナル プロセスに対して active_record が行っていること (Mac の同じバージョンでは見られない) が原因で、奇妙な動作をしているのですか? 例えば:

require 'rubygems'
trap("INT"){puts "interrupted"}
puts __LINE__
sleep 5
require 'active_record'
trap("INT"){puts "interrupted again"}
puts __LINE__
sleep 5

上記のコード (ruby 1.8.6、gem 1.3.1、activerecord 2.2.2) を実行すると、最初のスリープ中に何度でも ^C を押すことができますが、activerecord の要求後の最初の割り込みによって、終了するスクリプト。上記の場合、トラップは引き続き実行されますが、プログラムの続行が許可されないだけです。いつもの。

trap への 2 番目の呼び出しを削除しても、動作には何の影響もありません。

本当の煩わしさは、状況によっては、トラップの実行がまったく失敗することです。これを行うことの全体的なポイントは、コード自体をクリーンアップすることです (データベース内のフットプリントを削除して、次の人が正常な状態を確認できるようにすることです)、これは本当の問題です。例えば:

require 'rubygems'
require 'active_record'
trap("INT"){puts "interrupted"}
puts __LINE__
gets

プットを見た後に ^C を押しても、トラップはまったく実行されません。

この問題は、active_record を要求した後にのみ発生します。回避策はありますか? これがバグなのか、それとも何らかの説明があるのか​​ 知りたいです。私が言ったように、Mac ではこれに問題はありません。繰り返し ^C を実行すると、trap proc が複数回実行されます。

ありがとう...

4

2 に答える 2

1

これを行うことの全体的なポイントは、コード自体をクリーンアップすることです(データベース内のフットプリントを削除します...

データベース トランザクションのみを使用することを検討しましたか? 問題を解決するためのはるかに簡単な方法のようです。

于 2009-04-16T00:20:17.803 に答える
0

この問題を再現しようとすると、別のパターンが表示されました。

puts "start"
trap("INT") { puts "interrupted" }
sleep 5
puts "end"

Ubuntu(Ruby 1.8.6)では、これにより

start
interrupted
interrupted
(etc)
interrupted
end

したがって、「中断」は、Crtl-Cが押されるたびに、5秒が経過するまで印刷されます。Windows(Ruby 1.8.6も)では、これにより以下が生成されます。

start
interrupted
end

つまり、「中断」を1回印刷してから、終了します。

したがって、SIGINTを処理している間、Rubyはスリープルーチンを終了し、次のステートメントに進むように見えます。私の推測(手を振る)は、これはどういうわけか、RubyがWindowsのネイティブスレッドの代わりにグリーンスレッドを使用しているためだと思います。専門家はここでチャイムを鳴らしてください。

sleepハンドラーで再起動することにより、Unix-yの動作をエミュレートできます。

puts "start"
trap("INT") do 
  puts "interrupted"
  sleep 5
end
sleep 5
puts "end"

残念ながら、これはSIGINTがトラップされるたびにタイマーをリセットするため、ハッキングが必要です。

$interval = 5
def go_to_sleep(secs)
  $started = Time.now
  sleep secs
end
trap("INT") do 
  puts "interrupted"
  time_to_sleep = [0,$interval - (Time.now - $started)].max
  if time_to_sleep > 0
    sleep time_to_sleep
  end
end
puts "one"
go_to_sleep($interval)
puts "two"
go_to_sleep($interval)
puts "three"
go_to_sleep($interval)
于 2010-01-20T02:57:48.990 に答える