<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>trap::timeout</title> <meta http-equiv="Content-type" content="text/html; charset=UTF-8" /> <link href="default.css" type="text/css" rel="stylesheet" /> <link href="refm464.html" rel="next" /> <link href="refm462.html" rel="prev" /> <link href="index.html" rel="start" /> </head> <body> <div class="navigator"><span class="navigator">[<a href="index.html">MAIN</a>][<a href="refm543.html">INDEX</a>] [<a href="index.html">TOP</a>][<a href="refm439.html">UP</a>][<a href="refm462.html"><-PREV</a>][<a href="refm464.html">NEXT-></a>]</span></div> <hr /> <h1><a name="L008401" id="L008401">timeout</a></h1> <ul> <li><p>gethostbyname で timeout できない</p> <p>timeout は Thread で実現されているため、C レベルで停止してしまう (Threadの切替えが発生しない)処理に対しては効果がありません。</p> <p>以下の例では、gethostbyname(およそ0.6秒処理に時間がかかっている) が終了し た直後((A)の箇所)で TimeoutError 例外があがっています。</p> <pre>require 'timeout' require 'socket' start = Time.now begin timeout(0.1) { p TCPSocket.gethostbyname("www.ruby-lang.org") # (A) } ensure p Time.now - start end => ["helium.ruby-lang.org", [], 2, "210.251.121.214"] 0.689331 /usr/local/lib/ruby/1.6/timeout.rb:37: execution expired (TimeoutError) from -:6:in `timeout' from -:6</pre> <p>Rubyで書かれたリゾルバを利用するという回避策があります。 <code>require "resolv-replace"</code> すると、<code>resolv.rb</code> で定義された、 リゾルバが利用されるようになります。</p></li> <li><p>Windows版 Ruby で timeout できない</p> <p>Win32版 ruby (<a href="refm409.html">cygwin</a>、<a href="refm405.html">mingw</a>、<a href="refm403.html">mswin32</a>, <a href="refm407.html">bccwin32</a>)では、以下の場合も Thread の切替えが起こらないために timeout できません。</p> <pre># Win32ネイティブ版(mingw, mswin32, bccwin32) require 'timeout' begin timeout(5) do $stdin.gets end rescue TimeoutError print "timeout\n" end # Cygwin版 i = 0 begin timeout(5) do while true puts (i+=1) end end rescue TimeoutError print "timeout\n" end</pre> <p><a href="refm401.html">Win32ネイティブ版</a>では、$stdin.gets が、<a href="refm409.html">cygwin</a>版 では、 puts が Thread の切替えを発生させないようです。<a name="footmark:1" id="footmark:1" href="#foottext:1"><sup><small>*1</small></sup></a></p></li> </ul> <hr /> <p class="foottext"> <a name="foottext:1" id="foottext:1" href="#footmark:1"><sup><small>*1</small></sup></a><small>正確には cygwinで は <a href="refm538.html">setitimer(2)</a> にバグがある(らしい)ため Thread が切り替わらないようです。Cygwin版 ruby version 1.6.8 と 1.7.3 の最新では setitimer(2) を使わないようにすることでこの不具合が 修正されました<a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/36058">ruby-list:36058</a><sup class="outside"><small>[外部]</small></sup>, <a href="refm386.html">ruby 1.6 feature</a></small><br /> </p> <hr /> <div class="navigator"><span class="navigator">[<a href="index.html">MAIN</a>][<a href="refm543.html">INDEX</a>] [<a href="index.html">TOP</a>][<a href="refm439.html">UP</a>][<a href="refm462.html"><-PREV</a>][<a href="refm464.html">NEXT-></a>]</span></div> </body> </html>