Архитектура операционных систем и интерфейсы прикладного программирования

Автор: Пользователь скрыл имя, 20 Января 2011 в 12:43, лекция

Описание работы

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

Работа содержит 1 файл

Архитектура ОС и интерфейсы прикладного программирования.doc

— 278.00 Кб (Скачать)

     Поскольку нас интересует работа с параллельными  задачами, пусть при выполнении программы для каждого перечисленного в командной строке файла создается свой процесс или задача (тред), который параллельно с другими процессами (тредами) производит работу по подсчету пробелов в «своем» файле. Результатом работы программы будет являться список файлов с подсчитанным количеством пробелов для каждого.

     Следует обратить особое внимание на то, что приведенная ниже конкретная реализация данной задачи не является единственно возможной. В обеих рассматриваемых операционных системах существуют различные методы как работы с файловой системой, так и управления процессами. В данном случае рассматривается только один, но наиболее характерный для соответствующего API вариант.

Текст программы  для Windows (WinAPI)

     Для того чтобы было удобнее сравнивать эту и следующую программы, а  также из-за того, что настоящая  задача не требует для своего решения оконного интерфейса, в нижеприведенном тексте использованы только те вызовы API, которые не затрагивают графический интерфейс. Конечно, нынче редко какое приложение не использует возможностей GUI, но в нашем случае зато сразу можно увидеть разницу в организации параллельной работы запускаемых вычислений.

#include <windows.h>

#include <stdio.h> >

#include <stdlib.h>

 
// Название  processFile

// Описание исполняемый  код треда

// Входные параметры  lpFileName - имя файла для обработки

// Выходные параметры  нет

//

DWORD processFile(LPVOID IpFileName) {

HANDLE handle;         // описатель файла

DWORD numRead, total = 0;

char buf;

// запрос к ОС на открытие файла (только для чтения) handle = CreateFile( (LPCTSTR)lpFileName, GENERIC_READ,FILE_SHARE_READ,  NULL,  OPEN_EXISTING,  FILE_ATTRIBUTE_NORMAL, NULL),

 
// цикл чтения  до конца файла do {

    // чтение одного  символа из файла

    ReadFile( handle   (LPVOID) &buf,  1, &numRead, NULL);

    if (buf == 0x20) total++ } while ( numRead > 0):

fprintf(stderr,  "(ThreadID  %Lu), File %s  spaces = %d\n", GetCurrentThreadId(), lpFileName, total); 

// закрытие файла CloseHandle( handle).

  return(0) }

// Название main

// Описание главная  программа

// Входные параметры  список имен файлов для обработки

// Выходные параметры нет

//

int main(int argc, char *argv[]) {

int i;

DWORD pid;

HANDLE hThrd[255];     // массив ссылок на треды

// для всех  файлов, перечисленных в командной  строке for (i = 0, i< (argc-1),   i++) {

// запуск треда - обработка одного файла hThrd[i] = CreateThread( NULL, 0x4000, (LPTHREAD_START_ROUTINE) processFile,

        (LPVOID) argv[i+l], 0, &pid);

     fprintf(stdout,  "processFile started (HND=%d)\n", hThrd[i]); }

// ожидание окончания  выполнения всех запущенных тредов

    WaitForMu1tipleObjects( argc-1, hThrd, true,  INFINITE);

  return(0); }

  Обратите  внимание, чтo основная программа запускает треды и ждет окончания их выполнения.

Текст программы  для Linux (POSIX API)

#include <sys/types.h> #include <sys/stat.h>

#include <wait.h> #include <fcntl.h> #include <stdio.h>

// Название: processFile

// Описание: обработка  файла, подсчет кол-ва пробелов

// Входные параметры: fileName - имя файла для обработки

// Выходные параметры:  кол-во пробелов в файле

//

int processFile( char *fileName) {

    int handleб numRead, total = 0;

    char buf;

// запрос  к ОС на открытие файла (только  для чтения) handle = open( fileName, 0_RDONLY);

// цикл чтения  до конца файла do {

    // чтение одного  символа из файла

    numRead = read( handle, &buf, 1);

  if (buf == 0x20) total++; } while (numRead > 0);

  // закрытие файла close(handle): return(total); }

  // для  всех файлов, перечисленных в  командной строке for (i = 1, i< argc,  i++) { // запускаем дочерний процесс pid = fork(), if (pid == 0) { 

  // если  выполняется дочерний процесс  // вызов функции счета количества  пробелов в файле

  pnntf( "(PID: %d), File %s, spaces = %d\n", getpid(), argv[i],

  processFile( argv[i])); 

// выход  из процесса exit();

    }

  // если  выполняется родительский процесс  else 

 pnntf("processFile started (pid=%d)\n", pid); }

    // ожидание окончания  выполнения всех запущенных процессов

  if (pid != 0) while (wait(&status)>0);

  return; }

// Название: main

// Описание: главная  программа

// Входные параметры:  список имен файлов для обработки

// Выходные параметры: нет

//

int main(int argc. char *argv[]) { int i, pid, status; 

     Из  этого текста видно, что в этом случае все вычисления принимают  статус процессов, а не тредов.

     В заключение можно заметить, что очень  трудно сравнивать API. При их разработке создатели, как правило, стараются реализовать полный набор основных функций, используя которые можно решать различные задачи, хотя, порой, и различными способами. Один набор будет хорош для одного набора задач, другой — для иного набора задач. Тем более что фактически у нас сейчас существенно ограниченное множество API. Причина в том, что доминируют наиболее распространенные ОС, на распространение которых в большей степени оказали влияние не достоинства или недостатки этих ОС и их API, а правильная маркетинговая политика фирм, их создавших.

Информация о работе Архитектура операционных систем и интерфейсы прикладного программирования