2010-11-19 10 views
1

スレッドを連続して実行しようとしていて、tclメインイベントループによってブロックされないようにしようとしています。 infinite_loop PROCが呼び出され、メインイベントループが無限に実行され、このコードでメインイベントループによってtclスレッドがブロックされないようにします。

#!/bin/sh 
#\ 
exec tclsh "$0" "[email protected]" 

package require Thread 

set ::a_thread [thread::create {thread::wait}] 

proc start_a {} { 
    thread::send $::a_thread { 
    puts "Running a thread" 
    } 
    after 1000 a_start 
} 

proc infinite_loop {} { 
    while {1} { 
    puts "Loop" 
    after 500 
    } 
} 

start_a 
infinite_loop 

vwait forever 

: は、ここで私は何をしようとしているの簡単な例です。私はa_threadまだバックグラウンドで実行することができますが好きです。どうすればこれを達成できますか?

答えて

6

メインイベントループがスレッドをブロックしていません。代わりに、メインイベントループを使用してスレッド内で実行されるスクリプトをスケジュールします。代わりに、スレッド自体にスケジューラを実行します。

コードをテストし、期待どおりに動作:

thread::send $::a_thread { 
    proc loop {} { 
     puts "running a thread" 
     after 1000 loop 
    } 
    loop 
} 

while 1 { 
    puts "loop" 
    after 500 
} 
+0

ありがとうございました、Tclウィキの例は、このような状況を見逃していたようです。 – elmt

5

答えは、もちろん、slebetmanによって与えられたものです。しかし、この種のデバッグ方法(特に複雑な場合)は、各スレッドが出力するメッセージの末尾にthread::idの接頭辞を付けることです。ループを丸めます。たとえば、次のように他のスレッドで実行されているが(デフォルトで実行を終了するスクリプトのthread::send待ち)同期起こって、そして無限ループすることをされていることを、発送はかつて起こったことを言っただろう

package require Thread 

set ::a_thread [thread::create {thread::wait}] 

proc start_a {} { 
    puts "[thread::id]: Dispatch to $::a_thread" 
    thread::send $::a_thread { 
    puts "[thread::id]: Running a thread" 
    } 
    after 1000 a_start 
} 

proc infinite_loop {} { 
    while {1} { 
    puts "[thread::id]: Loop" 
    after 500 
    } 
} 

start_a 
infinite_loop 
puts "[thread::id]: Start main event loop" 
vwait forever 

メインイベントループの起動を妨げている(したがって、ディスパッチの再スケジューリング)。あなたは誰が何をしているのか分からなかったので、もちろん混乱がありました!

+0

非常に便利なチップ。これはスレッドのスレッドでの最初のスタブなので、これは私の将来のベンチャーに役立ちます。 – elmt

関連する問題