确定当前线程是否具有低I / O优先级

时间:2010-05-19 08:57:01

标签: c++ winapi io

if (reader.is_lazy()) goto tldr;

我有一个后台线程来完成一些I / O密集型后台类型的工作。为了取悦正在运行的其他线程和进程,我使用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上,它会通过使用过多的I / O来完全破坏系统。我有一个缓解此问题的丑陋和可耻方式的计划,但这取决于我能否确定当前线程是否具有低I / O优先级

现在,我知道我可以存储我最终设置的线程优先级,但程序中的控制流程并不适合这个。我希望以后能够测试当前线程是否具有低I / O优先级 - 如果它处于“后台模式”。

tldr:

GetThreadPriority似乎没有给我这个信息,它只给出了CPU优先级。

有没有办法确定当前线程的I / O优先级是否低?

2 个答案:

答案 0 :(得分:2)

如果您已将其设置为后台模式,则会失败。您是否可以依赖于您是否希望将其作为后台处理,而不仅仅是将优先级设置为后台开始并查看它是否失败?

如果您希望/不希望它,那么您可以通过调用后台结束进行测试。

如果这对您不利,那么您最好只使用线程本地存储来存储它是否处于后台模式。


Magnus Hoff编辑:这就是我最终实现它的方式:

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
    }
}

运作良好:)

答案 1 :(得分:0)

隐藏得很好,但是我发现了NtQueryInformationThreadIO_PRIORITY_HINT

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

ThreadIoPriority是THREADINFOCLASS枚举的一部分。