2012-08-30 68 views
2

我是tcl的新手。我想在tcl中創建一個線程,它應該保持在後臺調用自己。如何在tcl中創建線程8.4

#!/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爲,但我不明白如何使用它

回答

5

不要那樣做。相反,使用通常的Tcl成語來處理非阻塞通道:爲「通道可讀」事件設置一個處理程序,然後輸入事件循環;當設備將數據發送到您打開的端口時,操作系統將數據傳遞給您的應用程序,並調用回調。

一個最小的程序來演示這一概念看起來是這樣的:

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 

瞭解更多關於此in the examples

一些觀察:

  • 的EOF僅當遠程側關閉發生。如果您在頻道上致電close,則在這種情況下甚至不會調用「可讀」。
  • 如果你正在編寫一個Tk應用程序,它將已經有一個事件循環,所以不需要調用vwait(此外,他們強烈建議不要,因爲這將重新進入事件循環):你只是打開你的設備,例如在用戶點擊一個按鈕時執行的代碼中,在獲取的頻道上設置可讀回調,然後在該回調中執行其餘的處理(如上所示)。

閱讀this(及其鏈接)瞭解更多關於面向事件編程的信息。還有search wiki —它包含大量的例子和背景知識。

+0

感謝您的回覆。但是,上面的代碼也給我提供了同樣的問題,即使串行端口上沒有數據,它也不會從事件循環中出來並繼續搜索事件。如果我有一些其他事件需要處理,那麼在串行端口上沒有數據時可能會發生這種情況。總之,上述兩個代碼都會阻止我的系統,並且不允許執行任何操作。你能明白我在這裏說的意思嗎?如果是,請幫助我 – user1497818

+0

不,我不明白你的意思。使用事件循環精確地允許您忘記忙於等待數據:當數據可用時,您設置了一個要調用的命令前綴。您可以在任何給定時間在任意數量的頻道上安裝任意數量的回調。他們不會干涉每一個人。請注意,沒有「搜索事件」這樣的事情。基本上,當你調用'vwait'時,你的代碼將會有效地進入睡眠狀態,並且只有在有回調被註冊的事件時喚醒,並且回調纔會被執行。 – kostix