Проверьте, запущен ли поток Win32 или приостановлен
Как проверить, работает ли поток Win32 или находится в приостановленном состоянии?
Я не могу найти Win32 API, который дает состояние потока. Итак, как мне получить состояние потока?
8 ответов
Я думаю - изначально - эта информация не была предоставлена, потому что любой API, предоставляющий эту информацию, будет вводить в заблуждение и бесполезен.
Рассмотрим два возможных случая - текущий поток приостановил интересующий поток. Код в текущем потоке знает о приостановленном состоянии и должен иметь возможность делиться им, поэтому команде ядра не нужно добавлять API.
Во втором случае какой-то другой / третий поток в системе приостановил интересующий поток (и нет никакого способа отследить, какой поток был). Теперь у вас есть условие состязания - другой поток может в любой момент - приостановить интересующий поток, а информация, полученная из API, бесполезна - у вас есть значение, указывающее, что поток приостановлен, хотя на самом деле это не так.
Мораль истории - если вы хотите знать, что поток приостановлен, - приостановите его: возвращаемое значение из SuspendThread - это предыдущий счетчик приостановки потока. И теперь вы знаете что-то полезное - поток был и остается приостановленным - что полезно. Или что это не было (но сейчас) приостановлено. В любом случае, состояние потока теперь известно детерминистически, поэтому теоретически вы можете сделать несколько разумных решений на основе этого - либо ResumeThread, либо оставить его приостановленным.
Вы можете получить эту информацию, вызвав NtQuerySystemInformation() со значением для SystemProcessesAndThreadsInformation (целочисленное значение 5).
Если вам нужен пример того, что вы можете сделать с этой информацией, взгляните на Thread Status Monitor.
Хотя это не задокументировано - хотя это должно быть ИМХО, если вы вызываете WaitForSingleObject, он вернет WAIT_ABANDONED, если поток приостановлен. Кроме того, если поток завершен, его дескриптор будет в сигнальном состоянии.
Больше всего меня беспокоит, когда кто-то отвечает на ваши вопросы, говоря, почему у вас не должно быть ответа на ваш вопрос... Или начинает задавать вопросы, ПОЧЕМУ вы хотите это сделать. Когда кто-то находит этот вопрос в Google, причины, по которым ПОЧЕМУ не совпадают, и, таким образом, ответ сделает его бесполезным для кого-либо еще.
Класс WMI Win32_Thread имеет ThreadState
собственность, где 5: "Приостановлено заблокировано" и 6: Приостановлено Готово.
Вам понадобится идентификатор потока, чтобы получить правильный экземпляр напрямую (свойство Handle объекта WMI является идентификатором потока).
РЕДАКТИРОВАТЬ: учитывая этот запрос PowerShell:
gwmi win32_thread | group ThreadState
дает
Название группы ----- ---- ----- 6 2 {,,,...} 966 5 {,,,...}
WMI имеет другое определение "Приостановлено" для Win32.
Вы могли бы получить счетчик приостановки потока с кодом как это:
DWORD GetThreadSuspendCount(HANDLE hThread) {
DWORD dwSuspendCount = SuspendThread(hThread);
ResumeThread(hThread);
return dwSuspendCount;
}
но, как уже говорилось - это не точно. Более того, приостановка потока - это зло.
ДА: возможно получить состояние потока и определить, приостановлено ли оно.
И НЕТ: вам не нужна Windows 7 для этого.
Я опубликовал свой рабочий класс здесь на Stackru: как получить состояние потока (например, приостановлено), использование памяти + ЦП, время запуска, приоритет и т. Д.
Этот класс требует Windows 2000 или выше.
В Windows 7 вы можете использовать QueryUmsThreadInformation. (UMS означает планирование в режиме пользователя).
Смотрите здесь для UmsThreadIsSuspended
,
Я думаю, что государство здесь упоминается как
- Если поток находится в потоке, выполняющий некоторую обработку или
- В ожидании события
Об этом можно позаботиться, используя переменную, которая может сказать, что поток действительно запущен или ожидает события.
Эти сценарии появляются при рассмотрении пулов потоков, имеющих несколько n потоков и основанных на состоянии каждого потока, задачи могут быть назначены незанятым потокам.
К сожалению, нет. В зависимости от вашего кода, вы можете приблизиться к этому (устанавливая флаг всякий раз, когда вы, например, ожидаете объект ядра), но имейте в виду, что поток всегда может блокировать вызовы ОС или библиотеки, и вы не будете знать об этом.