そうしないでください。代わりに、非ブロック チャネルを操作するための通常の 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も検索してください。多くの例と背景知識が含まれています。