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

7
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 优先级?

GetThreadPriority为什么不起作用? - Goz
@Goz:它只提供了CPU优先级。我更新了问题,包括这一点。 - Magnus Hoff
2个回答

2

如果您已将其设置为后台模式,则会失败。根据您是否希望它成为后台处理,不要仅将优先级设置为background begin并查看是否失败。

如果您希望它不是后台处理,则可以通过调用background end来进行测试。

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


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

工作良好 :)


0

它非常隐蔽,但我找到了NtQueryInformationThreadIO_PRIORITY_HINT

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

ThreadIoPriority是THREADINFOCLASS枚举的一部分。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接