
- •Операционные системы для программиста
- •Введение
- •1. Основные понятия
- •1.1. Понятие операционной системы
- •1.2. Системные соглашения для доступа к функциям ос
- •1.3. Особенности разработки программ в базовых ос
- •1.4. Командный интерфейс пользователя в ос
- •1.5. Информация об ошибках системной функции
- •2. Программный доступ к файловой системе
- •2.1. Понятия дескрипторов, идентификаторов и хэндлов
- •2.2. Ввод и вывод в стандартные файлы.
- •2.3. Базовые средства использования файлов
- •2.4. Многопользовательская блокировка файлов
- •2.5. Установка произвольной позиции в файле
- •3. Принципы построения ос
- •3.1. Модульная структура построения ос
- •3.2. Использование прерываний в ос
- •3.3. Управление системными ресурсами
- •3.4 Строение ядра операционной системы
- •3.5. Структура операционной системы типа Windows nt
- •4. Многофункциональный консольный вывод
- •4.1. Функции управления курсором
- •4.2. Многократный вывод символов и атрибутов
- •4.3. Вывод в произвольную позицию экрана
- •4.4. Ввод данных, размещенных предварительно на экране
- •5. Системные функции ввода для консольных устройств
- •5.1. Системные функции ввода текстовых строк
- •5.2. Событийно-управляемый ввод
- •5.3. Системные функции ввода с клавиатуры
- •5.4. Опрос ввода с клавиатуры в программе
- •5.5. Системные функции мыши для текстового режима
- •6. Файловые системы
- •6.1. Структуры файловых систем для пользователя
- •6.2. Методы распределения внешней памяти
- •6.3. Принципы построения файловых систем типа fat
- •6.4. Современные модификации файловой системы fat
- •6.5. Особенности построения файловой системы hpfs
- •6.6. Принципы построения файловой системы ntfs
- •6.7. Особенности строения файловых систем для Unix
- •6.8. Программный опрос файловой системы
- •7. Обеспечение множественности процессов
- •7.1. Основные понятия теории вычислительных процессов
- •7.2. Программное порождение процессов
- •7.3. Уничтожение процессов
- •7.4. Ожидание завершения процессов
- •8. Многопоточное функционирование ос
- •8.1. Понятие нити и связь Хе с процессом
- •8.2. Создание нитей (thread) в программе
- •8.3. Уничтожение нитей
- •8.4. Приостановка и повторный запуск нити
- •8.5. Ожидание завершения нити
- •9. Средства взаимодействия программных единиц
- •9.1. Абстрактные критические секции
- •9.2. Абстрактные семафоры
- •9.3. Семафоры взаимоисключения
- •9.4. Семафоры событий
- •9.5. Средства группового ожидания
- •9.6. Программные критические секции
- •9.7. Программные семафоры с внутренним счетчиком
- •10. Управление памятью
- •10.1. Виртуальная память
- •10.2. ЏодкРчка страниц для реализациШ виртуальной памяти
- •10.3. Системные функции распределения памяти
- •10.4. Совместное использование памяти
- •10.5. Отображение файлов в оперативную память
- •10.6. Динамически распределяемая память
- •11. Средства коммуникации процессов
- •11.1. Неименованные коммуникационные каналы Unix
- •11.2. Переназначение хэндлов для доступа к каналу
- •11.3. Неименованные каналы в Windows
- •11.4. Именованные каналы в Windows nt
- •11.5. Именованные каналы в Unix
- •12. Взаимодействие пользователя с ос
- •12.1. Интерфейсы операционных систем
- •12.2. Командные и операционные оболочки (shells)
- •12.3. Основные команды базовых операционных систем
- •12.4. Групповое выполнение и фоновый запуск команд
- •12.5. Стандартный ввод-вывод и конвейеры командной строки
- •12.6. Командные файлы и сценарии
- •Библиографический список
1.3. Особенности разработки программ в базовых ос
Имея в виду учебный характер данного пособия, познакомим читателя с простейшими типовыми приемами разработки программ на языке Си для базовых операционных систем. Эти приемы основываются на вызове средств программирования в режиме командной строки. При таком программировании используется текстовое окно, часто размером во весь экран, на котором отображается все, что непосредственно вводится с клавиатуры. Программист набирает команды управления операционной системой или вызова служебных программ нажатием клавиш клавиатуры и нажимает клавишу Enter.
Как это ни странно, отказ от полноэкранных систем программирования и графического интерфейса значительно ускоряет разработку простейших программ, нужно лишь обладать необходимым минимумом знаний, чтобы командовать компьютером на этом уровне управления. Более сложные и громоздкие средства разработки на самом деле эффективны только для достаточно больших и сложных программ, а также для малоквалифицированных программистов, которым они в диалоговом режиме помогают разобраться в ряде типовых ситуаций. Лишь отладка программ с помощью специализированных отладчиков требует более мощных и громоздких средств.
Для программирования в операционной системе Windows основными современными средствами программирования на языке Си являются соответствующие программные продукты фирм Borland (более современное название Inprise Inc.) и Microsoft. Современные компиляторы первой из них называются BCC32.EXE, а второй – CL.EXE Исходный текст программы на языке Си может быть подготовлен в любом текстовом редакторе, формирующем чистый текст без всяких атрибутов и стилей. В Windows для этого подойдет редактор "Блокнот" (Notepad.exe), но лучше использовать файловую инструментальную оболочку типа FAR manager или подобную ей. Рекомендуется для простейших программ, использующих программные функции операционной системы, задавать расширение исходных файлов программ, обозначаемое буквой "с", так что типовой пример может быть наименован как prim.c. Создание исполняемой программы с помощью программы BCC32.EXE запишется в командной строке как
bcc32 prim.c
а с помощью программы CL.EXE запишется в командной строке как
cl prim.c
Если использовать систему программирования Watcom фирмы Sybase, приказ на создание исполняемой программы запишется в командной строке как
wcl386 prim.c
Читатель, видимо, уловил правило приказов на создание исполняемых программ: в командной строке записывается имя основной программы системы разработки, за которым через пробел (пробелы) записывается имя исходной программы. При повторных вызовах программ, уже вызывавшихся из командной строки, достаточно один (или более) раз нажать на клавишу клавиатуры (что вызывает в командную строку предыдущую или более раннюю использованную команду), затем следует нажать клавишу Enter (в командных оболочках для вызова предыдущей выполненной команды может использоваться другая управляющая клавиша).
Этот простейший прием в случае ошибок в исходной программе приводит к выводу их непосредственно на текстовый экран (экран консоли), что при многочисленных ошибках может быть неудобно разработчику. Для вывода сообщений об ошибках в файл, имя которого выбрано разработчиком, любую из приведенных выше команд надо дополнить фрагментом вида
>имяфайладляошибок
Например, вызов компилятора BCC32 с помещением информации об ошибках в файл myerrs.lst для исходного текста программы prima.c запишется как
bcc32 prima.c >myerrs.lst
Для использования отладчика подготовительные действия несколько усложняются. Вызов компилятора BCC32.EXE должен содержать опцию (ключ) v, которой должен предшествовать символ дефиса или наклонной черты (символ - или /), так что наш пример приобретает вид
bcc32 -v prim.c
В системе разработки Microsoft отсутствует отладчик, отделенный от интегрированной системы разработки Visual Studio, поэтому желающие могут использовать всю эту систему.
В системе разработки Watcom опцией задания отладочной информации служит буквосочетание d2, поэтому соответствующий вызов компилятора должен иметь вид
wcl386 -d2 prim.c
Для разработок программ в операционной системе Linux служит свободно распространяемый компилятор с общим именем gcc. Его вызов для компиляции исходной программы prim.c задается в командной строке в виде
gcc prim.c
Неожиданностью для программистов, начинающих разработки под Unix, является отсутствие исполняемого файла вида prim.exe. Дело в том, что расширение exe для исполняемых файлов в этой системе не является употребительным, хотя никак и не запрещается. Более того, автоматически создаваемый компилятором исполняемый файл имеет имя a.out (достаточно непривычно для типовых пользователей операционных систем от MS). Чтобы задать любое желаемое имя исполняемого файла, следует воспользоваться опцией -o, которая призвана определять имя выходного (output) файла и за которой через пробел (пробелы) должно следовать это имя. В нашем примере следует набрать командный текст
gcc -o prim.exe prim.c
В стандартной настройке ОС Unix для запуска программы, как правило, недостаточно набрать в командной строке ее имя. Обычно вызов программы из текущего оглавления задается в виде
./имяпрограммы
Причины этого, связанные с особенностями файловой системы и стремлением увеличить защищенность ОС от несанкционированного доступа, будут рассмотрены позже.
Для последующего использования отладчика в вызове компилятора следует задать опцию -g, так что общий вызов будет иметь вид
gcc -o prim.exe -g prim.c
Сам отладчик имеет в этой системе имя gdb, а вызов на выполнение программы под управлением отладчика будет записываться в виде
gdb prim.exe
Данный отладчик несет многие консервативные следы предыдущих поколений операционной системы Unix, и его изучение является отдельной темой.
Все разработки в операционной системе Windows требуют подключения заголовочного файла windows.h, в операционной системе Unix в простейших случаях бывает достаточно ограничиться подключением заголовочного файла stdio.h или unistd.h – в современных версиях этих операционных систем.
Более детальная информация будет даваться при рассмотрении примеров.