Определите, имеет ли текущий поток низкий приоритет ввода / вывода - PullRequest
6 голосов
/ 19 мая 2010
if (reader.is_lazy()) goto tldr;

У меня есть фоновый поток, который выполняет некоторые операции ввода-вывода с интенсивным фоновым типом. Чтобы угодить другим выполняющимся потокам и процессам, я установил приоритет потока в «фоновом режиме», используя SetThreadPriority, например:

SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN);

Однако THREAD_MODE_BACKGROUND_BEGIN доступен только в Windows Server 2008 или более поздней версии, а также в Windows Vista и более поздних версиях, но программа также должна хорошо работать на Windows Server 2003 и XP. Таким образом, реальный код больше похож на это:

if (!SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN)) {
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);
}

Проблема в том, что в Windows XP она полностью нарушит работу системы при использовании слишком большого количества операций ввода-вывода. У меня есть план для отвратительного и постыдного способа решения этой проблемы, но это зависит от того, смогу ли я определить, имеет ли текущий поток низкий приоритет ввода / вывода или нет.

Теперь я знаю, что могу сохранить, какой приоритет потока я в конечном итоге установил, но поток управления в программе не совсем подходит для этого. Я бы предпочел иметь возможность позже проверить, имеет ли текущий поток низкий приоритет ввода / вывода - находится ли он в «фоновом режиме».

tldr:

GetThreadPriority, кажется, не дает мне эту информацию, он только дает приоритет процессора.

Есть ли способ определить, имеет ли текущий поток низкий приоритет ввода / вывода?

Ответы [ 2 ]

2 голосов
/ 19 мая 2010

Ну, это не удастся, если вы уже установили его в фоновом режиме. Не могли бы вы, в зависимости от того, хотите ли вы, чтобы это была фоновая обработка, а не просто установить приоритет начала фона и посмотреть, не получится ли это?

Если вы ожидаете / хотите, чтобы этого не было, вы можете проверить это, вызвав фоновый конец.

Если это нехорошо для вас, лучше всего использовать локальное хранилище потоков для хранения данных в фоновом режиме или нет.


Редакция Магнуса Хоффа: Вот так я и реализовал это:

bool has_low_io_priority() {
    if (SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN)) {
        // Seems we were able to enter background mode. That means we were
        // not in background mode from before.
        SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_END);
        return false;
    } else {
        DWORD err = GetLastError();
        if (err == ERROR_THREAD_MODE_ALREADY_BACKGROUND) return true;
        else return false; //< Background mode is not available at all
    }
}

Хорошо работает:)

0 голосов
/ 04 апреля 2019

Это очень хорошо спрятано, но я нашел NtQueryInformationThread и IO_PRIORITY_HINT .

IO_PRIORITY_HINT priority;
ULONG returnLength;
NtQueryInformationThread(hThread, ThreadIoPriority, &priority, sizeof(priority), &returnLength);

ThreadIoPriority является частью перечисления THREADINFOCLASS .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...