Пример: многопоточный поиск контекста

Пример: многопоточный поиск контекста

В программе 6.1 (grepMP) для выполнения одновременного поиска текстового шаблона в нескольких файлах использовались процессы. Программа 7.1 (grepMT), которая включает исходный код функции поиска текстового шаблона grep, обеспечивает выполнение поиска несколькими потоками в рамках одного процесса. Код функции поиска основан на вызовах функций файлового ввода/вывода библиотеки С. Основная программа аналогична той, которая предлагалась в варианте реализации, основанном на использовании процессов.

Этот пример также показывает, что применение потоков позволяет выполнять асинхронные операции ввода/вывода даже без привлечения специально для этого предназначенных методов, описанных в главе 14. В данном примере параллельным вводом/выводом с участием нескольких файлов управляет программа, в то время как основной или любого другого потока предоставляется возможность в ожидании завершения ввода/вывода выполнять дополнительную обработку. По мнению автора, способ реализации асинхронного ввода/вывода, обеспечиваемый потоками, является более простым, а сравнительный анализ эффективности различных методов, представленный в главе 14, поможет вам выработать собственное мнение на этот счет.

Мы увидим, однако, что в сочетании с портами завершения ввода/вывода операции асинхронного ввода/вывода становятся очень полезным, а часто и необходимым средством в тех случаях, когда количество потоков очень велико.

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

Наконец, обратите внимание на ограничение в 64 потока, обусловленное значением константы MAXIMUM_WAIT_OBJECTS, которая ограничивает количество дескрипторов при вызове функции WaitForMultipleObjects. Если у вас возникнет необходимость в большем количестве потоков, организуйте для функций WaitForSingleObjects или WaitForMultipleObjects соответствующий цикл.

Предостережение

Программа grepMP осуществляет асинхронный ввод/вывод в том смысле, что отдельные потоки выполняют параллельное синхронное чтение различных файлов, которые блокируются до момента завершения операции чтения. Можно также организовать параллельное чтение одного и того же файла, если у него имеются различные дескрипторы (обычно, по одному дескриптору для каждого потока). Эти дескрипторы должны быть сгенерированы функцией CreateFile, а не функцией DuplicateHandle. В главе 14 описывается асинхронный ввод/вывод, осуществляемый как с использованием, так и без использования пользовательских потоков, а в примере, доступном на Web-сайте (программа atouMT, описанная в главе 14), операции ввода/вывода выполняются с использованием нескольких потоков по отношению к одному и тому же файлу.

Программа 7.1. grepMT: многопоточный поиск текстового шаблона 

/* Глава 7. grepMT. */

/* Параллельный поиск текстового шаблона — версия, использующая несколько потоков. */

#include "EvryThng.h"

typedef struct { /* Структура данных потока поиска. */

 int argc;

 TCHAR targv[4][МАХ_РАТН];

} GREP_THREAD_ARG;

typedef GREP_THREAD_ARG *PGR_ARGS;

static DWORD WINAPI ThGrep(PGR_ARGS pArgs);

int _tmain(int argc, LPTSTR argv[]) {

 GREP_THREAD_ARG * gArg;

 HANDLE * tHandle;

 DWORD ThdIdxP, ThId, ExitCode;

 TCHAR CmdLine[MAX_COMMAND_LINE];

 int iThrd, ThdCnt;

 STARTUPINFO Startup;

 PROCESS_INFORMATION ProcessInfo;

 GetStartupInfo(&StartUp);

 /* Основной поток: создает отдельные потоки поиска на основе функции "grep" для каждого файла. */

 tHandle = malloc((argc – 2) * sizeof(HANDLE));

 gArg = malloc((argc – 2) * sizeof(GREP_THREAD_ARG));

 for (iThrd = 0; iThrd < argc – 2; iThrd++) {

  _tcscpy(gArg[iThrd].targv[1], argv[1]); /* Pattern. */

  _tcscpy(gArg[iThrd].targv[2], argv[iThrd + 2]);

  GetTempFileName /* Имя временного файла. */

   (".", "Gre", 0, gArg[iThrd].targv[3]); 

  gArg[iThrd].argc = 4;

  /* Создать рабочий поток для выполнения командной строки. */

  tHandle[iThrd] = (HANDLE)_beginthreadex(NULL, 0, ThGrep, &gArg[iThrd], 0, &ThId);

 }

 /* Перенаправить стандартный вывод для вывода списка файлов. */

 Startup.dwFlags = STARTF_USESTDHANDLES;

 Startup.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);

 /* Выполняются все рабочие потоки. Ожидать их завершения. */

 ThdCnt = argc – 2;

 while (ThdCnt > 0) {

  ThdIdxP = WaitForMultipleObjects(ThdCnt, tHandle, FALSE, INFINITE);

  iThrd = (int)ThdIdxP – (int)WAIT_OBJECT_0;

  GetExitCodeThread(tHandle [iThrd], &ExitCode);

  CloseHandle(tHandle [iThrd]);

  if (ExitCode ==0) { /* Шаблон найден. */

   if (argc > 3) {

    /* Вывести имя файла, если имеется несколько файлов. */

    _tprintf(_T(" **Результаты поиска – файл: %s "), gArg[iThrd].targv [2]);

    fflush(stdout);

   }

   /* Использовать программу "cat" для перечисления результирующих файлов. */

   _stprintf(CmdLine, _T("%s%s"), _Т("cat "), gArg [iThrd].targv[3]);

   CreateProcess(NULL, CmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &StartUp, &ProcessInfo);

   WaitForSingleObject(ProcessInfo.hProcess, INFINITE);

   CloseHandle(ProcessInfo.hProcess);

   CloseHandle(ProcessInfo.hThread);

  }

  DeleteFile(gArg[iThrd].targv[3]);

  /* Скорректировать массивы потоков и имен файлов. */

  tHandle[iThrd] = tHandle[ThdCnt – 1];

  _tcscpy(gArg[iThrd].targv[3], gArg[ThdCnt – 1].targv[3]);

  _tcscpy(gArg[iThrd].targv[2], gArg[ThdCnt – 1].targv[2]);

  ThdCnt--;

 }

}

/* Прототип функции контекстного поиска:

static DWORD WINAPI ThGrep(PGR_ARGS pArgs){ } */

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

6.4 СОХРАНЕНИЕ КОНТЕКСТА ПРОЦЕССА

Из книги Архитектура операционной системы UNIX автора Бах Морис Дж

6.4 СОХРАНЕНИЕ КОНТЕКСТА ПРОЦЕССА Как уже говорилось ранее, ядро сохраняет контекст процесса, помещая в стек новый контекстный уровень. В частности, это имеет место, когда система получает прерывание, когда процесс вызывает системную функцию или когда ядро выполняет


6.4.3 Переключение контекста

Из книги Программирование в X Window средствами Free Pascal автора Полищук А П

6.4.3 Переключение контекста Если обратиться к диаграмме состояний процесса (Рисунок 6.1), можно увидеть, что ядро разрешает производить переключение контекста в четырех случаях: когда процесс приостанавливает свое выполнение, когда он завершается, когда он возвращается


6.4.4 Сохранение контекста на случай аварийного завершения

Из книги Язык программирования С# 2005 и платформа .NET 2.0. [3-е издание] автора Троелсен Эндрю

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


1.2.2 Характеристики графического контекста

Из книги Применение Windows API автора Легалов А И

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


Границы контекста объекта

Из книги Основы AS/400 автора Солтис Фрэнк

Границы контекста объекта Итак, вы могли убедиться, что домены приложения – это логические разделы в рамках процесса, предназначенные для загрузки компоновочных блоков .NET. Домен приложения, в свою очередь, можно делить дальше на контекстные области со своими границами.


Проверка контекста объекта

Из книги Системное программирование в среде Windows автора Харт Джонсон М

Проверка контекста объекта Из тех приложений, которые вы построите сами, очень немногие могут потребовать программного взаимодействия с контекстом, но вот вам пример для иллюстрации подхода, о котором идет речь. Создайте новое консольное приложение с именем ContextManipulator.


Обертка для контекста устройств

Из книги Программирование на языке Пролог для искусственного интеллекта автора Братко Иван

Обертка для контекста устройств Холст или контекст устройств WindowsПеревод А. И. ЛегаловаАнглоязычный оригинал находится на сервере компании Reliable SoftwareЧтобы раукрашивать, рисовать или печатать в окне, Вам необходим контекст устройств (device context или, кратко, DC). DC — это


Аппаратное переключение контекста

Из книги Разработка приложений в среде Linux. Второе издание автора Джонсон Майкл К.

Аппаратное переключение контекста Так как только что описанным процедурам обработки исключений может потребоваться доступ к привилегированным командам PowerPC, механизм прерываний должен иметь возможность переключать состояние процессора при передаче управления


Пример: параллельный поиск указанного текстового шаблона

Из книги QNX/UNIX [Анатомия параллелизма] автора Цилюрик Олег Иванович

Пример: параллельный поиск указанного текстового шаблона Настало время посмотреть на процессы Windows в действии. Приведенная ниже в качестве примера программа grepMP создает процессы для поиска указанного текстового шаблона в файлах, по одному процессу на каждый файл. Эта


Резюме: безопасный многопоточный код

Из книги Искусство программирования на языке сценариев командной оболочки автора Купер Мендель

Резюме: безопасный многопоточный код Прежде чем мы приступим к рассмотрению объектов синхронизации, ознакомьтесь с пятью начальными рекомендациями, соблюдение которых будет гарантировать корректное выполнение программ в многопоточной среде.1. Переменные, являющиеся


12.7.1. Получение контекста сигнала

Из книги автора

12.7.1. Получение контекста сигнала Информация о том, как и почему был сгенерирован сигнал, называется контекстом[68] сигнала. Приложения, которые должны видеть этот контекст, используют обработчики сигналов, отличающиеся от нормальных. Они включают два дополнительных


Многопоточный менеджер

Из книги автора

Многопоточный менеджер Следующим шагом развития техники менеджера ресурсов является многопоточный менеджер. Фактически это объединение техники менеджера ресурсов с динамическим пулом потоков, рассмотренным выше.Реальный работающий многопоточный менеджер с


Вытеснение и переключение контекста

Из книги автора

Вытеснение и переключение контекста Переключение контекста — это переключение от одной, готовой к выполнению задачи к другой. Это переключение производится с помощью функции context_switch(), определенной в файле kernel/sched.c. Данная функция вызывается функцией schedule(), когда новый