2

私はtclが初めてです。バックグラウンドで自分自身を呼び出し続けるスレッドを tcl で作成したいと考えています。

#!/usr/bin/env tclsh

set serPort [open "/dev/ttyS0" RDWR]

fconfigure $serPort  -mode 115200,n,8,1 -blocking 0 

while { 1 } {
set data [gets  $chan]
puts $data

}

上記の while ループの使用を避け、while ループ内の機能に対して繰り返し可能なスレッドを作成したいと考えています。基本的に、PC の COM1 をデバイスに接続し、デバイスからシリアル データを取得しています。しかし、ポートにデータがない場合、「eof」コマンドを使用してもループから抜けません。それが私がスレッドを作成したい理由です。

そのために Tcl_CreateThread を使用する予定ですが、使用方法がわかりません

4

1 に答える 1

5

そうしないでください。代わりに、非ブロック チャネルを操作するための通常の Tcl のイディオムを使用します。「チャネル読み取り可能」イベントのハンドラを設定し、イベント ループに入ります。開いたポートにデバイスがデータを送信すると、OS はそのデータをアプリケーションに渡し、コールバックが呼び出されます。

概念を実証するための最小限のプログラムは次のようになります。

proc my_read_handler ch {
    set data [read $ch]
    if {[eof $ch]} {
        close $ch
        set ::forever done ;# this makes the call to `vwait` below to quit
        return
    }
    # Otherwise process the data here ...
}

set serPort [open "/dev/ttyS0" RDWR]

fconfigure $serPort -mode 115200,n,8,1 -blocking no
fileevent $serPort readable [list my_read_handler $serPort]

vwait ::forever ;# the program enters the event loop here

詳細については、例を参照してください。

いくつかの観察:

  • EOF は、リモート側が閉じたときにのみ発生します。チャネルで呼び出す場合close、この場合、「読み取り可能」は呼び出されません。
  • Tk アプリケーションを作成している場合は、既にイベント ループがあるため、 を呼び出すvwait必要はありません (さらに、これはイベント ループに再び入るため、これは強くお勧めしません): デバイスを開くだけで、たとえば、ユーザーがボタンをクリックしたときに実行されるコードでは、取得したチャネルで読み取り可能なコールバックを設定し、そのコールバックで残りの処理を行うだけです (上記を参照)。

イベント指向プログラミングの詳細については、これ (およびそこにあるリンク) を参照してくださいwikiも検索してください。多くの例と背景知識が含まれています。

于 2012-08-30T14:05:37.753 に答える