ã“ã‚“ã«ã¡ã¯ã€
ãƒãƒ³ã‚µãƒ³ã§ã™ã€‚
ã“ã®ãƒ¡ãƒ¼ãƒ«ã¯ã“ã®å‰ã€ruby-coreã«ï¼ˆruby-core:11584)英語ã§é€ã£ãŸã‚“ã§ã™ã‘ã©ã€ç”ãˆãŒãªã‹ã£ãŸã‹ã‚‰ruby-devã«ã€ä»Šå›žæ—¥æœ¬èªžã§ã€é€ã‚ã†ã¨æ€ã£ãŸã‚“ã§ã™â€¦
Mac OS Tiger(10.4)ã§ã¯ã€ã“ã†ã„ã†å•é¡ŒãŒã‚ã£ã¦ï¼š
% ruby -ve ‘require “timeout” ; Timeout.timeout(5) { puts df -h
}’
ruby 1.8.6 (2007-06-07 patchlevel 36) [i686-darwin8.10.1]
/usr/local/lib/ruby/1.8/timeout.rb:54: execution expired
(Timeout::Error)
from /usr/local/lib/ruby/1.8/timeout.rb:56:in `timeout’
from -e:1
patchlevel
39ã§ã‚‚åŒã˜å•é¡ŒãŒèµ·ã“ã‚Šã¾ã™ã€‚ã§ã™ã‘ã©–disable-pthreadsã‚’ã¤ã„ãŸã‚‰ã€ãã‚Œã¨ã‚‚1.8ã®ãƒ–ランãƒã‚„1.8.6-p0ã§ã¯ã€å•é¡Œã¯èµ·ã“らãªã„ã§ã™ã€‚
ã‚‚ã£ã¨èª¿ã¹ãŸã‚‰ã€æ¸ˆã‚“ã§ãªã„関数ã¯rb_thread_cancel_timer
(eval.c)。ã“ã®é–¢æ•°ã¯1.8.6-p36ã‚„-p39ã ã‘ã§proc_exec_v (process.h)ã«å‘¼ã°ã‚Œã¦ã¾ã™ã€‚
ãã—ã¦pthreadを使ã‚ãªã„å ´åˆã€ã“ã®é–¢æ•°ãŒç©ºã£ã½ã«ãªã‚Šã¾ã™
ãã‚Œã§rb_thread_cancel_timerã§å®Ÿéš›ã«ä½•ãŒèµ·ã“ã‚‹ã®ã‹ã€ãã—ã¦ã©ã†ã—ã¦Tiger以外ã®OS(Linux,
Leopard…)ã§ã©ã†ã—ã¦å•é¡ŒãŒèµ·ã“らãªã„ã‹ã‚’調ã¹ãŸã‚“ã§ã™ã€‚ç†ç”±ãŒTigerã®ãƒã‚°ã§ã‚ã‚‹ã¿ãŸã„ã§ã™ã€‚
実際ã«Rubyã®system()ã‚„``を使ã£ãŸã‚‰èµ·ã“ã‚‹ã®ãŒã“ã†ã„ã†ã“ã¨ï¼š
*プãƒã‚»ã‚¹ãŒãƒ•ã‚©ãƒ«ã‚¯ã•ã‚Œã¦ã€è¦ªãŒèˆˆå‘³ã‚ã‚‹ã“ã¨ã‚’ã—ãªã„。ã§ã‚‚åã¯ä»¥ä¸‹ã®ã“ã¨ã‚’ã™ã‚‹ã€‚
*timer
threadã‚’killã™ã‚‹ãŸã‚ã«ã€rb_thread_cancel_timerãŒå‘¼ã°ã‚Œã¦ã„る。ã ã‘ã©ã“ã®ãƒ—ãƒã‚»ã‚¹ã¯ãƒ•ã‚©ãƒ«ã‚¯ã§ä½œã‚‰ã‚Œã¦ã‚‹ã‹ã‚‰ã€timer
threadãŒãªã„(forkã¯åã§ã¯current
thread以外全ã¦ã®threadを殺ã™ï¼‰ã€‚ãã‚Œã§ã€åã®å¤‰æ•°ã®time_threadãŒè¦ªã®threadã‚’å‚ç…§ã™ã‚‹ã€‚ã“ã®threadãŒã“ã®ãƒ—ãƒã‚»ã‚¹ã®threadã§ãªã„ã‹ã‚‰å¤§éƒ¨åˆ†ã®OSã§ã¯rb_thread_cancel_timerã®pthread_cancelã¨pthread_joinã®ä¸¡æ–¹ã‚‚失敗ã™ã‚‹ã€‚ã‘ã©ã€Tigerã§ã¯pthread_cancelãŒæˆåŠŸã™ã¦pthread_cancelãŒæ°¸é ã«å¾…ã¤ã€‚
ã©ã†ã—ã¦rb_thread_cancel_timerãŒå‘¼ã°ã‚ŒãŸã‹ã‚’調ã¹ãŸã‚‰ï¼ˆruby-dev:30581)ã€ã“ã‚Œã¯æ¶ˆã›ãªã„ã¨æ€ã„ã¾ã™ã€‚ã§ã‚‚Cã®forkã®åã‹ã‚‰ç›´æŽ¥å‘¼ã¶ã®ã‚‚ダメã§ã™ã€‚
ã“ã®ãƒ¡ãƒ¼ãƒ«ã«å°ã•ã„(pthread_atforkを使ã£ã¦ã‚‹ï¼‰ãƒ‘ッãƒã‚’添付ã—ãŸã‚“ã§ã™ã€‚ã§ã‚‚ã“ã®ãƒ‘ッãƒã¯æœ¬å½“ã«æ£ã—ã„ç›´ã—æ–¹ã§ã‚ã‚‹ã‹ã©ã†ã‹â€¦ã‚ã‹ã‚‰ãªã„ã§ã™ã€‚