Составители:
Рубрика:
мощью функции PostQueuedCompletionStatus надо будет поме-
щать в очередь порта запросы, имитирующие завершение ввода-
вывода.
Рассмотрим небольшой пример (проверка ошибок для упрощения
пропущена):
#include <process.h>
#define _WIN32_WINNT 0x0500
#include <windows.h>
#define MAXQUERIES 15
#define CONCURENTS 3
#define POOLSIZE 5
unsigned __stdcall PoolProc( void *arg );
int main( void )
{
int i;
HANDLE hcport, hthread[ POOLSIZE ];
DWORD temp;
/* создаем порт завершения ввода-вывода */
hcport = CreateIoCompletionPort(
INVALID_HANDLE_VALUE, NULL, NULL, CONCURENTS
);
После создания порта надо создать пул потоков. Число потоков в пу-
ле обычно превышает число одновременно работающих потоков, задавае-
мое при создании порта:
/* создаем пул потоков */
for ( i = 0; i < POOLSIZE; i++ ) {
hthread[i] = (HANDLE)_beginthreadex(
NULL,0,PoolProc,(void*)hcport,0,(unsigned*)&temp
);
}
Если созданный порт ассоциирован с одним или несколькими файла-
ми, то после завершения асинхронных операций ввода-вывода в очереди
порта будут размещаться асинхронные запросы, которые система будет на-
правлять для обработки потокам из пула. Однако порт завершения ввода-вы-
вода можно и не связывать с файлами – тогда для размещения запроса мож-
но воспользоваться функцией PostQueuedCompletionStatus, которая размеща-
ет запросы в очереди без выполнения реальных операций ввода-вывода.
Разработка параллельных приложений для ОС Windows
221
Эта функция выполняет две разных операции – во-первых, она соз-
дает новый порт завершения, и, во-вторых, она ассоциирует порт с завер-
шением операций ввода-вывода с заданным файлом. Обе эти операции
могут быть выполнены одновременно одним вызовом функции, а могут
быть исполнены раздельно. Более того, вторая операция – ассоциирова-
ние порта завершения ввода-вывода с реальным файлом – может вообще
не выполняться. Две типичных формы применения функции
CreateIoCompletionPort:
1. Создание нового порта завершения ввода-вывода:
#define CONCURRENTS 4
HANDLE hCP;
hCP = CreateIoCompletionPort(
INVALID_HANDLE_VALUE, NULL, NULL, CONCURRENTS
);
При простом создании порта завершения ввода-вывода доста-
точно указать только максимальное число одновременно рабо-
тающих потоков (здесь CONCURRENTS, целесообразно ограничи-
вать числом доступных процессоров). Далее, когда будет созда-
ваться пул потоков, в нем можно будет создать и большее число
потоков, чем указано при создании порта – система будет отсле-
живать, чтобы одновременно исполнялся код не более чем ука-
занного числа потоков. При этом поток, перешедший в состоя-
ние ожидания, не считается исполняющимся, так что в случае
потоков, проводящих часть времени в режиме ожидания, имеет
смысл создавать пул потоков большего размера, чем указано
при вызове функции CreateIoCompletionPort.
2. Ассоциирование порта с файлом:
#define SOME_NUMBER 123
CreateIoCompletionPort( hFile, hCP, SOME_NUMBER, 0 );
В этом варианте функция CreateIoCompletionPort не создает но-
вого порта, а возвращает переданный ей описатель уже сущест-
вующего. Существующий порт завершения ввода-вывода мож-
но связать с несколькими различными файлами одновременно;
при этом процедура, обслуживающая завершение ввода-вывода,
сможет различать, операция с каким именно файлом поставила
в очередь данный запрос, с помощью параметра CompletionKey
(здесь SOME_NUMBER), назначаемого разработчиком. Созданный
порт можно не ассоциировать ни с одним файлом – тогда с по-
220
CIL и системное программирование в Microsoft .NET
220 CIL и системное программирование в Microsoft .NET Разработка параллельных приложений для ОС Windows 221 Эта функция выполняет две разных операции – во-первых, она соз- мощью функции PostQueuedCompletionStatus надо будет поме- дает новый порт завершения, и, во-вторых, она ассоциирует порт с завер- щать в очередь порта запросы, имитирующие завершение ввода- шением операций ввода-вывода с заданным файлом. Обе эти операции вывода. могут быть выполнены одновременно одним вызовом функции, а могут Рассмотрим небольшой пример (проверка ошибок для упрощения быть исполнены раздельно. Более того, вторая операция – ассоциирова- пропущена): ние порта завершения ввода-вывода с реальным файлом – может вообще не выполняться. Две типичных формы применения функции #includeCreateIoCompletionPort: #define _WIN32_WINNT 0x0500 1. Создание нового порта завершения ввода-вывода: #include #define CONCURRENTS 4 #define MAXQUERIES 15 #define CONCURENTS 3 HANDLE hCP; #define POOLSIZE 5 hCP = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, NULL, CONCURRENTS unsigned __stdcall PoolProc( void *arg ); ); При простом создании порта завершения ввода-вывода доста- int main( void ) точно указать только максимальное число одновременно рабо- { тающих потоков (здесь CONCURRENTS, целесообразно ограничи- int i; вать числом доступных процессоров). Далее, когда будет созда- HANDLE hcport, hthread[ POOLSIZE ]; ваться пул потоков, в нем можно будет создать и большее число DWORD temp; потоков, чем указано при создании порта – система будет отсле- /* создаем порт завершения ввода-вывода */ живать, чтобы одновременно исполнялся код не более чем ука- hcport = CreateIoCompletionPort( занного числа потоков. При этом поток, перешедший в состоя- INVALID_HANDLE_VALUE, NULL, NULL, CONCURENTS ние ожидания, не считается исполняющимся, так что в случае ); потоков, проводящих часть времени в режиме ожидания, имеет После создания порта надо создать пул потоков. Число потоков в пу- смысл создавать пул потоков большего размера, чем указано ле обычно превышает число одновременно работающих потоков, задавае- при вызове функции CreateIoCompletionPort. мое при создании порта: 2. Ассоциирование порта с файлом: /* создаем пул потоков */ #define SOME_NUMBER 123 for ( i = 0; i < POOLSIZE; i++ ) { CreateIoCompletionPort( hFile, hCP, SOME_NUMBER, 0 ); hthread[i] = (HANDLE)_beginthreadex( NULL,0,PoolProc,(void*)hcport,0,(unsigned*)&temp В этом варианте функция CreateIoCompletionPort не создает но- ); вого порта, а возвращает переданный ей описатель уже сущест- } вующего. Существующий порт завершения ввода-вывода мож- Если созданный порт ассоциирован с одним или несколькими файла- но связать с несколькими различными файлами одновременно; ми, то после завершения асинхронных операций ввода-вывода в очереди при этом процедура, обслуживающая завершение ввода-вывода, порта будут размещаться асинхронные запросы, которые система будет на- сможет различать, операция с каким именно файлом поставила правлять для обработки потокам из пула. Однако порт завершения ввода-вы- в очередь данный запрос, с помощью параметра CompletionKey вода можно и не связывать с файлами – тогда для размещения запроса мож- (здесь SOME_NUMBER), назначаемого разработчиком. Созданный но воспользоваться функцией PostQueuedCompletionStatus, которая размеща- порт можно не ассоциировать ни с одним файлом – тогда с по- ет запросы в очереди без выполнения реальных операций ввода-вывода.
Страницы
- « первая
- ‹ предыдущая
- …
- 115
- 116
- 117
- 118
- 119
- …
- следующая ›
- последняя »