Tcl одновременный секундомер и счетчик не работают

У меня есть секундомер TK/TCL, запускающий счетчик unix из xterm, но он не отображает счетчик на изображении счетчика. После завершения счетчика unix (у него 4 итерации) отображается дисплей секундомера и ведется подсчет. Как продолжать показывать счет после нажатия на кнопку запуска?

секундомер с кнопками управления

Вот код (замените соответствующее «желание» в строке 3):

#!/bin/sh
####################################################################### \
exec /sw/freetools/tk/8.5.6/Linux/rh5/x86_64/bin/wish8.5 "$0" ${1+"$@"}
package require Tk

wm title . "TEST-GUI"
. configure -padx 50 -pady 50 -relief raised -borderwidth 2

###STOPWATCH -begin-
set COLOR_BACKGROUND "black"
set COLOR_FOREGROUND "sky blue"
font create FONT0 -family {VL PGothic} -size -20 -weight normal
set ::time 00:00:00

proc every {ms body} {
 eval $body
 after $ms [namespace code [info level 0]]
}
proc Start {} {
 if {$::time eq {00:00:00}} {
  set ::time0 [clock clicks -milliseconds]
 }
 every 10 {
  set m [expr {[clock clicks -milliseconds] - $::time0}]
  set ::time [format %2.2d:%2.2d:%2.2d [expr {$m/60000}] [expr {($m/1000)%60}] [expr {$m%1000/10}]]
 }
 .frame1.run config -state disabled
}
proc Stop {} {
 if {[llength [after info]]} {
  after cancel [after info]
 } else {set ::time 00:00:00}
 .frame1.run config -state normal
}
###STOPWATCH -end-


frame .frame1 -highlightbackground black \
              -highlightthickness 1 \
              -width 200 -height 200

label .frame1.time -textvar ::time -font FONT0 -background $COLOR_BACKGROUND -foreground $COLOR_FOREGROUND

button .frame1.run -text "RUN" -foreground black -bg coral \
                               -borderwidth 3 -height 0 -width 3 -font {-family symbol -size 8} -pady 2 \
                               -command {
                             Start
                         gui_run
                                        }

button .frame1.exit -text "EXIT" -foreground black \
                     -borderwidth 3 -height 0 -width 3 -font {-family symbol -size 8} -pady 2 \
                                 -command {exit}

pack .frame1
pack .frame1.run -side top
pack .frame1.exit -side bottom
pack .frame1.time

proc xterm_counter {} {
 set fileid [open "./xterm_counter.txt" w]
 puts $fileid "#!/bin/csh -f"
 puts $fileid ""
 puts $fileid "set i = 0"
 puts $fileid "echo \"testing programm counting -start- \`date +%X\`\""
 puts $fileid "while (\$i <= 3)"
 puts $fileid " sleep 2"
 puts $fileid " set i = \`expr \$i + 1\`"
 puts $fileid " echo \"testing programm counting here => \$i\""
 puts $fileid "end"
 puts $fileid "echo \"testing programm counting -end-   \`date +%X\`\""
 close $fileid
}

proc gui_run {} {
 xterm_counter
 exec chmod 744 "./xterm_counter.txt"
 if {[catch {exec ./xterm_counter.txt >@ stdout}]} {
  puts "RUN FAILED, exit programm"
  exit
 } else {
  puts "RUN SUCCESSFULL, stop stopwatch now"
 }
}

person cyl cyl    schedule 21.10.2019    source источник
comment
Я не уверен, что вы имеете в виду, но счет в счетчике отображается нормально в Windows (счетчик запускается при нажатии кнопки запуска)   -  person Jerry    schedule 22.10.2019
comment
Да, счетчик unix отображается в unix xterm, но при запуске счетчика в окне TK он временно останавливается, и когда счетчик unix завершается, в окне счетчика TK отображается обратный отсчет...   -  person cyl cyl    schedule 23.10.2019
comment
Думаю, я знаю, чем это вызвано; когда код выполняется, рисование приостанавливается до тех пор, пока выполнение не станет бездействующим. Вы можете изучить потоки. Я сам не знаком с этим, поэтому сомневаюсь, что буду чем-то полезен :(   -  person Jerry    schedule 23.10.2019
comment
Спасибо, я думаю использовать некоторые команды потоковой передачи, у меня есть несколько ответов ниже.   -  person cyl cyl    schedule 30.10.2019


Ответы (1)


Проблема в том, что команда exec приостанавливает процесс Tcl до тех пор, пока другой процесс не завершит работу. Это не большая проблема для чего-то быстрого, например, запуска chmod, но для долго работающего дисплея таймера это большая проблема.

Самое простое исправление, особенно если вас не особо волнует, работает ли подпроцесс, состоит в том, чтобы поместить слово & в конец exec, чтобы код выполнялся в фоновом режиме, отключенный от Tcl.

exec ./xterm_counter.txt >@stdout &

(Это возвращает идентификатор процесса, если я правильно помню, что позволяет вам периодически тянуть для завершения.)

Если это не работает для вас, вы можете либо запустить код в конвейере (с таким перенаправлением это будет канал только для записи), либо запустить его из рабочего потока.

person Donal Fellows    schedule 27.10.2019
comment
Спасибо. Работает хорошо. Но теперь я планирую остановить секундомер, когда счетчик закончится. Я должен работать над этим. - person cyl cyl; 30.10.2019