2015-02-04 3 views
0

Я начинаю в Tcl. Я пытаюсь изучить Tcl без участия в Tk. Я наткнулся на команды, такие как vwait и after, но я был смущен, поскольку большинство объяснений включало понятие event loop и далее в основном продемонстрировали концепцию с помощью Tk. Я хотел бы понять понятие событий и цикла событий и то, как команды, о которых я упоминаю, относятся к ним, просьба ссылаться на некоторые рекомендации для этого. Эксплантация не должна использовать Tk в качестве примеров, не используйте расширения Tcl, не предполагайте предварительного знания событий. Некоторые (минимальные) примеры игрушек и приложение real-wordl цикла tcl, за исключением программирования GUI/Tk, будут оценены.Контур события в Tcl

Я наткнулся на это tutorial на вики Tclers. Я ищу ДРУГИЕ ссылки или объяснения, подобные этому.

ответ

4

Если вы не используете Tk, основные причины использования цикла событий предназначены для ожидания в фоновом режиме, когда вы выполняете какую-либо другую задачу, связанную с I/O, и для обработки серверных сокетов.

Давайте рассмотрим серверные сокеты.

При открытии сервера сокета с:

socket -server myCallbackProcedure 12345 

Вы устраивая для обработчика событий, чтобы быть установлен на сокете сервера, так что, когда есть входящее соединение, что соединение превращает вас нормальное socket и предлагаемая вами процедура обратного вызова (myCallbackProcedure) вызывается для взаимодействия с сокетом. Это часто делается путем установки обработчика fileevent, так что поступающие данные обрабатываются, когда они поступают, а не блокируют ожидающий его процесс, но это необязательно.

Контур события? Это фрагмент кода, который вызывает в ОС (через select(), poll(), WaitForMultipleObject() и т. Д., В зависимости от ОС и вариантов сборки), чтобы ждать, пока что-то не произойдет на любом назначенном канале или не произойдет тайм-аут. Это очень эффективно, так как поток, вызывающий вызов, может быть приостановлен во время ожидания. Если что-то происходит, вызов ОС возвращается, а Tcl устраивает соответствующие вызовы. (Есть внутренняя очередь.) Это цикл, потому что, как только события обрабатываются, нормально возвращаться и ждать еще немного. (Это то, что делает Tk, до тех пор, пока нет никаких окон для его контроля, и что делает vwait до тех пор, пока переменная, которую он ждет, не задана каким-либо обработчиком событий.)

Асинхронные ожидания управляются с помощью упорядоченной по времени очереди, и перевести на установку тайм-аута на вызов в ОС.

Пример:

socket -server myCallbackProcedure 12345 
proc myCallbackProcedure {channel clientHost clientPort} { 
    puts "Connection from $clientHost" 
    puts $channel "Hi there!" 
    flush $channel 
    close $channel 
} 
vwait forever 
# The “forever” is an idiom; it's just a variable that isn't used elsewhere 
# and so is never set, and it indicates that we're going to run the process 
# until we kill it manually. 

Несколько более сложный пример с обработкой асинхронного соединения таким образом, мы можем обслуживать несколько соединений одновременно (ЦП необходимо: минимальное):

socket -server myCallbackProcedure 12345 
proc myCallbackProcedure {channel clientHost clientPort} { 
    puts "Connection from $clientHost" 
    fileevent $channel readable [list incoming $channel $clientHost] 
    fconfigure $channel -blocking 0 -buffering line 
    puts $channel "Hi there!" 
} 
proc incoming {channel host timeout} { 
    if {[gets $channel line] >= 0} { 
     puts $channel "You said '$line'" 
    } elseif {[eof $channel]} { 
     puts "$host has gone" 
     close $channel 
    } 
} 
vwait forever 

Еще более сложный пример который закроет соединения через 10 секунд (= 10000 мс) после последнего сообщения о них:

socket -server myCallbackProcedure 12345 
proc myCallbackProcedure {channel clientHost clientPort} { 
    global timeouts 
    puts "Connection from $clientHost" 
    set timeouts($channel) [after 10000 [list timeout $channel $clientHost]] 
    fileevent $channel readable [list incoming $channel $clientHost] 
    fconfigure $channel -blocking 0 -buffering line 
    puts $channel "Hi there!" 
} 
proc incoming {channel host timeout} { 
    global timeouts 
    after cancel $timeouts($channel) 
    if {[gets $channel line] >= 0} { 
     puts $channel "You said '$line'" 
    } elseif {[eof $channel]} { 
     puts "$host has gone" 
     close $channel 
     unset timeouts($channel) 
     return 
    } 
    # Reset the timeout 
    set timeouts($channel) [after 10000 [list timeout $channel $host]] 
} 
proc timeout {channel host} { 
    global timeouts 
    puts "Timeout for $host, closing anyway..." 
    close $channel 
    unset -nocomplain timeouts($channel) 
} 
vwait forever 
Смежные вопросы