Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
SysSoft.doc
Скачиваний:
520
Добавлен:
16.03.2016
Размер:
4.36 Mб
Скачать

Пример программирования в различныхApiос

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

Постановка задачи: необходимо подсчитать количество пробелов в текстовых фай­лах, имена которых должны указываться в командной строке. Рассмотрим два варианта программы, решающей эту задачу, – для Windows(с использованием WinAPI) и дляLinux(POSIXAPI).

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

Следует обратить особое внимание на то, что приведенная ниже конкретная реа­лизация данной задачи не является единственно возможной. В обеих рассматриваемых операционных системах существуют различные методы как работы с файловой системой, так и управления процессами. В данном случае рассматривается только один, но наиболее характерный для соответствующего 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 == 0х20) total++;

} while ( numRead > 0);

fprintf( stderr, "(ThreadID: %Lu), File %s, spaces = %d\n",

GetCurrentThreadId(), IpFileName, 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, 0х4000,

(LPTHREAD_START_ROUTINE) processFile, (LPVOID) argv[i+1], 0, &pid);

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

}

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

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

return(0);

}

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]