2017-03-24 11 views
1

を設定されていないupvar変数を送信する:子スレッドを返すようにするためにこのコードを保持しているの.tclファイルを調達した後TCLスレッド::私はこのようなコード持って

package require Thread 

proc p1 {} { 

    set tid [thread::create { 
     proc executeCommand {command} { 
      return $command 
     } 
     thread::wait 
    }] 

    set result "" 
    ::thread::send -async $tid [list executeCommand {"Hello thread world"}] result 

    #***Do some additional stuff*** 

    vwait result 
    ::thread::release $tid 
    puts $result 

    return $result 

} 

p1 

を、私の期待はこんにちは」でありますvwaitが呼び出された後の「スレッドワールド」と、出力される 'result'変数がありますが、どちらも起こりません。 'result'変数は空白のままです。

プロシージャ(proc)ブロックからコードを取り出して.tclファイルをソースすると、それは完璧に動作しますが、システムがセットアップされた状態でプロシージャを使用する必要があります。

私が間違っていることがわかりません。

答えて

1

「問題」は、受信変数(vwaitと同じ)が現在のスコープにある変数ではなく、グローバル名前空間に対して配置されていることです。フラグTCL_GLOBAL_ONLYthe call to Tcl_SetVar2Ex in the callbackに使用されている(とTclの基本的な変数の実装はそれほど1が実際にAPI、可能な場合に固執したい複雑さ):あなたはから戻ってきた可能性があるので、一般的に理にかなって

​​

バックグラウンドスレッドを起動して結果を受け取るまでの手順、そしてTcl は実際にはの初期バインディングを避けようとしています。

結果はどこに行きましたか?

% puts $::result 
"Hello thread world" 

このための最も簡単な修正がある受信を行うために、変数を使用することです:それは(::は単に「私は本当にこの名前のグローバル変数を使用することを意味」を意味する)グローバルresult変数にあります特定の呼び出しに固有です。

proc p1 {} { 
    set tid [thread::create { 
     proc executeCommand {command} { 
      return $command 
     } 
     thread::wait 
    }] 

    ### Make the name of the global variable (an array element) ### 
    set var ::p1results($tid) 

    ### This is a simple transformation of what you were already doing ### 
    set $var "" 
    ::thread::send -async $tid [list executeCommand {"Hello thread world"}] $var 

    #***Do some additional stuff*** 

    vwait $var 

    ### Transfer the global variable into a local and remove the global ### 
    set result [set $var] 
    unset $var 

    ### Back to your code now ### 
    ::thread::release $tid 
    puts $result 

    return $result 
} 

これは私がそれをしようとすると、期待通りに動作するように表示されます。我々はすでにスレッドIDでユニークなトークンを持っているので、どちらが、それが実際よりもより複雑に聞こえます。

+0

はい!これは完全に動作します - 素早く正確な応答のためにDonalに感謝します。 – Jake

関連する問題