Книга: Linux программирование в примерах
1.4.4. Вещи, которые делают программы GNU лучше
1.4.4. Вещи, которые делают программы GNU лучше
Теперь мы рассмотрим раздел, озаглавленный «Написание надежных программ», в главе 4 «Поведение программ для всех программ». Этот раздел описывает принципы проектирования программного обеспечения, которые делают программы GNU лучше их двойников в Unix Мы процитируем выбранные части главы, с несколькими примерами случаев, в которых эти принципы окупились.
Избегайте произвольных ограничений длины или числа любой структуры данных, включая имена файлов, строки, файлы и символы, выделяя все структуры данных динамически. В большинстве инструментов Unix «длинные строки молча срезаются». Это неприемлемо в инструменте GNU.
Это правило, возможно, единственное наиболее важное в проектировании программного обеспечения GNU — никаких произвольных ограничений. Все инструменты GNU должны быть способны обрабатывать произвольные объемы данных.
Хотя это требование, возможно, усложняет работу программиста, оно облегчает жизнь пользователю. С одной стороны, у нас есть пользователь gawk
, регулярно запускающий программу awk
для более чем 650 000 файлов (нет, это не опечатка) для сбора статистики, gawk
заняла бы более 192 мегабайтов пространства данных, и программа работала бы в течение 7 часов. Он не смог бы запустить эту программу, используя другую реализацию awk
.[22]
Утилиты, читающие файлы, не должны удалять символы NUL или любые другие неотображаемые символы, включая символы с кодами больше 0177. Единственными здравыми исключениями были бы утилиты, специально предназначенные для связывания с определенными типами терминалов или принтеров, которые не могут обработать эти символы.
Также хорошо известно, что Emacs может редактировать любые произвольные файлы, включая файлы, содержащие двоичные данные!
По возможности, программы должны обрабатывать должным образом последовательности байтов, представляющих многобайтные символы, используя такие кодировки, как UTF-8 и другие.[23] Каждый системный вызов проверяйте на предмет возвращенной ошибки, если вы не хотите игнорировать ошибки. Включите текст системной ошибки (от perror
или эквивалентной функции) в каждое сообщение об ошибке, возникшей при неудачном системном вызове, также, как и имя файла, если он есть, и имя утилиты. Простого «невозможно открыть foo.с» или «ошибка запуска» недостаточно.
Проверка каждого системного вызова создает устойчивость. Это еще один случай, когда жизнь программиста труднее, а пользователя легче. Подробно описанное сообщение об ошибке значительно упрощает нахождение и разрешение проблем[24].
Наконец, мы цитируем главу 1 GNU Coding Standards, которая обсуждает, как написать вашу программу способом, отличным от того, каким написаны программы Unix.
Например, утилиты Unix обычно оптимизированы для минимизации использования памяти, если вы взамен хотите получить скорость, ваша программа будет сильно отличаться. Вы можете хранить весь входной файл в ядре и сканировать его там. вместо использования stdio. Используйте недавно открытый более изящный алгоритм вместо алгоритма Unix-программы. Исключите использование временных файлов. Делайте это в один проход вместо двух (мы сделали это на ассемблере) Или, напротив, сделайте упор на простоте вместо скорости. Для некоторых приложений скорость сегодняшних компьютеров делает адекватными более простые алгоритмы.
Или выберите обобщение. Например, программы Unix часто содержат статичные таблицы или строки фиксированного размера, которые создают произвольные ограничения, используйте вместо этого динамическое выделение памяти. Убедитесь, что ваша программа обрабатывает во входных файлах символы NUL и другие курьезные символы. Добавьте язык программирования для расширяемости и напишите часть программы на этом языке.
Или выделите части программы в независимо используемые библиотеки. Или используйте простой сборщик мусора вместо точного отслеживания, когда освобождать память, или используйте новую возможность GNU, такую как obstacks.
Великолепным примером того, какое отличие можно сделать в алгоритме, является GNU diff
. Одним из первых ранних воплощений нашей системы было AT&T 3B1, система с процессором МС68010, огромными двумя мегабайтами памяти и 80 мегабайтами на диске. Мы проделали (и делаем) кучу исправлений в руководстве для gawk
, файле длиной почти 28 000 строк (хотя в то время он был лишь в диапазоне 10 000 строк). Обычно мы частенько использовали 'diff -с
', чтобы посмотреть на сделанные нами изменения. На этой медленной системе переключение на GNU diff
показало ошеломительную разницу во времени появления контекста diff
. Разница почти всецело благодаря лучшему алгоритму, который использует GNU diff
.
В последнем параграфе упоминается идея структурирования программы как независимо используемой библиотеки, с оболочкой командной строки или другим окружающим се интерфейсом. Примером этого является GDB, отладчик GNU, который реализован в виде инструмента с интерфейсом командной строки поверх отладочной библиотеки. (Разделение основных возможностей GDB от интерфейса командной строки является продолжающимся проектом). Эта реализация дает возможность создать поверх отладочных функциональных возможностей графический интерфейс отладчика.
- 1.4. Почему программы GNU лучше
- 1.4.5. Заключительные соображения по поводу «GNU Coding Standards»
- СТРУКТУРА ПРОСТОЙ ПРОГРАММЫ
- ПРИМЕР ПРОСТОЙ ПРОГРАММЫ НА ЯЗЫКЕ СИ
- Улучшенная производительность
- Улучшенный оптимизатор запросов
- Улучшенная стратегия вычисления предиката IN и условий, объединенных по OR
- Улучшенное время отклика для версии SuperServer
- Улучшенный протокол локальных соединений (XNET)
- 1.2.5. Пример программы
- «Вещи» как носители корпоративных стандартов
- Appendix H. GNU Free Documentation License