0

スレッド内からvwaitを終了するように変数を設定できる必要があります。これは、通常はインターペレーターをロックするループがあり、それが完了するまで実行中のGUIがあるためです。

私はそれが次のようなsleepコマンドのように機能することを望んでいます:

global EndSleep
after ${SleepTime_ms} set EndSleep 1
vwait EndSleep

デバイスを照会しているwhileループが終了するときに、vwait変数を設定する必要があるのは私だけです。

現在の私のコードは次のとおりです。

    proc ::VISA::Wait {VisaAlias} {
    # Link global variable
    global EndWait

    # Execute commands in a thread so the GUI is not locked while executing
    set Thread [thread::create]
    thread::send ${Thread} [list set VisaAlias ${VisaAlias}]
    thread::send ${Thread} {
        source MolexVisa.tcl

        # Temporarily make new connection with device
        VISA::Connect ${VisaAlias}

        # Query operation complete bit
        VISA::Query ${VisaAlias} "*OPC?"

        # Continue to attempt to read OPC bit until any response is given; typically 1
        while {[string equal [VISA::Read ${VisaAlias}] ""]} {}

        # Destroy temporary connection
        VISA::Disconnect ${VisaAlias}

        # Set vwait variable
        set EndWait 1
    }

    # Wait for thread to end
    vwait EndWait

    # Mark thread for termination
    thread::release ${Thread}
}

現在、スレッドはまだGUIをフリーズしています。また、スレッド内の変数と私が期待している変数は同じではないので、明らかにそれは永遠に待つだけです。

アドバイスや助けをいただければ幸いです。タスクを達成するための他のより実用的な方法をすべて使い果たしたと思いますが、もう少し洞察を歓迎します。

4

1 に答える 1

2

-asyncのフラグを使用しthread::sendます。デフォルトで::thread::sendは、スクリプトが実行されるまでブロックされます(これにより、ほとんどの場合、スレッドの使用が無効になります)。

フラグを使用する場合は、その-asyncためのオプションの変数引数を使用することもできますthread::sendvwait

set tid [thread::create {
    proc fib n {
        if {$n == 0 || $n == 1} {return 1}
        return [expr {[fib [expr {$n - 1}]] + [fib [expr {$n - 2}]]}]
    }
    thread::wait
}]
::thread::send -async $tid [list fib $num] result
vwait result
::thread::release $tid
# ... do something with result

これにより、GUIがフリーズするのを防ぐことができます。このフィボナッチの実装は最善ではなく、「高価な計算」のプレースホルダーであることに注意してください。

于 2013-02-12T06:50:22.270 に答える