TCL зависает при попытке закрыть трубу TCL - PullRequest
0 голосов
/ 12 сентября 2010

При запуске tclsh и наборе этого:

close [open "|tclsh" w]

все работает нормально.

Но, когда в ~/.tclshrc у вас есть package require Tk, та же самая строка делает tclsh для HANG!

Та же проблема возникает со всеми пакетами с графическим интерфейсом, такими как Tk, Itk, Img, Iwidgets, однако с не пакетами с графическим интерфейсом, такими как Itcl, все нормально.

Как я могу решить эту проблему?Смысл в том, чтобы tclsh не зависал при наборе close [open "|tclsh" w] с package require Tk в ~/.tclshrc.

Та же проблема с wish.close [open "|wish" w] хочет HANG (с пустым файлом ~/.wishrc)!

Я получил эту проблему как на 32-, так и на 64-битном CentOS.У меня есть следующие версии пакетов: tcl-8.5.8, tk-8.5.8, img-1.3, itcl-3.4.b1, itk-3.3, iwidgets-4.0.1.

Ответы [ 2 ]

2 голосов
/ 13 сентября 2010

Tcl-приложения в основном завершают работу после завершения сценария, независимо от того, предоставляется он интерактивно или нет.Однако пакет Tk меняет положение вещей так, что когда достигается конец сценария, он вместо этого входит в цикл обработки событий.Если вы полагаетесь на конец файла, вызывающий завершение работы, это будет выглядеть как зависание, но на самом деле оно просто ожидает правильного завершения работы приложения с графическим интерфейсом (поэтому оно может сообщить о состоянии завершения подпроцесса).

Исправление состоит в том, чтобы сделать читаемый каналом обработчик событий для stdin в подпроцессе.Есть несколько способов сделать это подробно, но вот простой, который может идти в конце основной части кода, которую вы обычно отправляете:

proc ReadFromStdin {} {
    if {[gets stdin line] >= 0} {
        uplevel "#0" $line
    } elseif {[eof stdin]} {
        exit
    } else {
        # Partial read; try later when rest of data available
    }
}
fileevent stdin readable ReadFromStdin

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

1 голос
/ 12 сентября 2010

Я бы подумал, что он ждет желания закончить работу, согласно man-странице:

Если channelId является блокирующим каналом для командный конвейер потом ждет close для дочерних процессов для завершения.

Поскольку wish входит в бесконечный цикл (цикл обработки событий) и никогда не завершается, команда close будет зависать. В том же духе [пакет требует Tk] (я полагаю) запускает цикл обработки событий, поэтому будет вызывать то же поведение.

Я признаю, что он загружает .tclshrc, так как

Если существует файл .tclshrc (или tclshrc.tcl на платформах Windows) в домашнем каталоге пользователя, интерактивный tclsh оценивает файл как сценарий Tcl непосредственно перед чтением первой команды из стандартного ввода.

Мне кажется странным, что [open "| tclsh" w] оказывается в интерактивной оболочке.

Как примечание: [pacakge требует Tk] кажется очень странной вещью в .tclshrc. Теоретически, вам не всегда нужен Tk (окно и цикл обработки событий) при запуске Tcl (т. Е. Приложения только из командной строки) ... и, когда вы этого хотите, вы знаете, что это так. Полагаю, каждому из них это кажется странным.

...