Давайте посмотрим, что у нас получилось. Этот сценарий по своему духу напоминает сценарий в примере 10.28. Тем не менее, благодаря реструктуризации программного кода, сценарий в примере 10.29 имеет значительное преимущество: так как на этот раз операция чтения данных выполняется в дочернем потоке, графический интерфейс остается отзывчивым. Операции перемещения окна, изменения его размеров и так далее, выполняются немедленно, потому что графический интерфейс не блокируется в ожидании вывода очередной порции данных программой командной строки. Комбинация канала, потока выполнения и очереди в этом примере творит чудеса — графическому интерфейсу не приходится ждать дочернюю программу, а дочернему потоку не требуется обновлять графический интерфейс.
Несмотря на сложность реализации и необходимость использовать многопоточную модель выполнения, отсутствие блокировок в примере 10.29 делают его функцию redirectedGuiShellCmd намного более полезной, чем в оригинальной версии. Тем не менее, в сравнении с реализацией на основе сокетов из предыдущего раздела, данное решение выглядит как смесь разных приемов:
• Поскольку эта реализация графического интерфейса читает данные из стандартного потока вывода дочерней программы, отпадает необходимость вносить в нее какие-либо изменения. В отличие от примера из предыдущего раздела, основанного на применении сокетов, программе командной строки не требуется знать о существовании графического интерфейса, отображающего ее результаты, — ей не требуется выполнять подключение к сокету и выталкивать свои выходные буферы, как в предыдущем решении с сокетами.
• Несмотря на отсутствие необходимости вносить изменения в программу, вывод которой отображается, сложность реализации графического интерфейса начинает приближаться к сложности реализации варианта на основе сокетов, особенно если отбросить шаблонный программный код, необходимый в любой программе, использующей сокеты.
• Данное решение не поддерживает возможность выполнения графического интерфейса и программы командной строки независимо друг от друга или на разных компьютерах. Как мы увидим в главе 12, сокеты позволяют передавать данные между программами, работающими на одном и том же компьютере, или по сети.
• Сокеты могут применяться не только для отображения стандартного потока вывода программы. Если от графического интерфейса требуется нечто большее, чем отображение вывода другой программы, сокеты могут обеспечить более универсальное решение. Кроме того, как мы увидим далее, сокеты по своей природе являются двунаправленными потоками данных, поэтому они позволяют передавать данные между программами в обоих направлениях более произвольными способами.
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, I том, 2011