Реферат: Эффективная многопоточность
Итак, мы знаем, как работает порт завершения ввода/вывода, когда потоки добавляются в пул и когда удаляются. Но сколько потоков должно быть в пуле? В два раза больше, чем число процессоров. Это очень общая рекомендация, и для некоторых задач она не подходит. По большому счету имеется только два критерия, по которым можно определять, нужно создавать новый поток или нет. Эти критерии – загруженность процессора и число пакетов запросов. Если число пакетов превышает определенное количество, и загруженность процессора невысока, есть смысл создать новый поток. Если пакетов мало, или процессор занят более чем на 90 процентов, дополнительный поток создавать не следует. Удалять поток из пула нужно, если он давно не обрабатывал клиентские запросы (просто подсчитать, сколько раз GetQueuedCompletionStatus вернула управление по таймауту). При удалении потока нужно следить, чтобы закончились все асинхронные операции ввода/вывода, начатые этим потоком.
Надо сказать, что определение загруженности процессора, количества пакетов в очереди порта и наличия у потока незавершенных операций ввода/вывода – задачи не самые простые. Например, вы можете использовать WMI для определения загруженности процессора, но при этом не сможете определить, есть ли у потока незавершенные операции ввода/вывода. Ниже я приведу функции получения вышеперечисленных показателей только недокументированными способами (здесь используется заголовочный файл ntdll.h из [3]):
// Функция получения загруженности процессора double GetCPUUsage() { #define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 \ + (double)((x).LowPart)) typedef NTSTATUS (NTAPI ZwQuerySystemInformation_t)( IN NT::SYSTEM_INFORMATION_CLASS SystemInformationClass, OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength OPTIONAL ); static ZwQuerySystemInformation_t* ZwQuerySystemInformation = 0; if(!ZwQuerySystemInformation) { ZwQuerySystemInformation = (ZwQuerySystemInformation_t*)GetProcAddress( GetModuleHandle(_T("ntdll.dll")), _T("NtQuerySystemInformation")); } double dbIdleTime = 0; static NT::LARGE_INTEGER liOldIdleTime = {0, 0}; static NT::LARGE_INTEGER liOldSystemTime = {0, 0}; // Получаемчислопроцессоров NT::SYSTEM_BASIC_INFORMATION sysinfo = {0}; NT::NTSTATUS status = ZwQuerySystemInformation(NT::SystemBasicInformation, &sysinfo, sizeof sysinfo, 0); if(status != NO_ERROR) return -1; // Получаем системное время К-во Просмотров: 408
Бесплатно скачать Реферат: Эффективная многопоточность
|