Похоже, что в примере отсутствует обработка промывки выходной стороны труб. Данные буферизуются в буферах ОС (ожидая, когда будет создано несколько килобайт), вместо того, чтобы фактически быть немедленно отправлены другому процессу. Обратите внимание, что эта буферизация происходит только тогда, когда вывод направлен на что-то, кроме терминала, поэтому вы не увидите его при интерактивном тестировании. (Также не важно, если пишется много данных, когда улучшенная эффективность этой буферизации является победителем.)
На стороне C добавьте эту строку вверху функции main
:
setvbuf(stdout, NULL, _IONBF, 0);
Со стороны Tcl добавьте это сразу после запуска подпрограммы:
fconfigure $mathModule -buffering none
Сторона C также может быть сделана с помощью fflush
после каждого printf
. Если вы застряли с настоящей программой на C, к которой у вас нет доступа к источнику, вы все равно можете добиться прогресса, обернув всю программу программой unbuffer
(на самом деле это скрипт Tcl, использующий магию с Expect для заставьте подпроцесс думать, что он разговаривает с терминалом). Недостатком unbuffer
является то, что он использует виртуальный терминал, который поступает из гораздо более ограниченного пула ресурсов, чем простые старые идентификаторы процессов (не говоря уже о каналах / дескрипторах файлов).