Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как узнать состояние потока? простой казалось бы вопрос 
:(
    Опции темы
DmitryHT
Дата 27.9.2007, 16:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 31.8.2007

Репутация: нет
Всего: нет



Как узнать состояние потока?

Т.е. как безошибочно определить состояние потока учитывая то, что поток мог быть еще не запущен, либо уже завершен, либо в процессе.


Нужно для того, чтобы определить свободен ли данный поток для запуска.
Код

potok: array[1..5000] of tPotok;
potok[i].Create = ?


p.s. возможно туплю... smile , но не судите строго
PM MAIL   Вверх
Alix
Дата 27.9.2007, 17:02 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


L45
**


Профиль
Группа: Участник
Сообщений: 581
Регистрация: 4.5.2005
Где: Pskov/Spb

Репутация: 7
Всего: 23



Возможно, так.
Код

  if Assigned(potok[i]) then  // Assigned(x) = "x <> nil"
    // busy
  else
    // run

Все зависит от того как ты их завершаешь. Как?


--------------------
Знание только тогда знание, когда оно приобретено усилиями своей мысли, а не памятью (с) Л. Толстой
High tech. Low live. (с) Gardner Dozois
PM MAIL ICQ Skype   Вверх
DmitryHT
Дата 27.9.2007, 17:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 31.8.2007

Репутация: нет
Всего: нет



Цитата

Все зависит от того как ты их завершаешь. Как?


вот так:
Код

potok[i].FreeOnTerminate(True);


Добавлено через 7 минут и 56 секунд
Alix, в твоем случае срабатывает только когда поток еще не запускался.
После первого запуска он становится Assigned даже не смотря на potok[i].FreeOnTerminate(True);
PM MAIL   Вверх
Rennigth
Дата 27.9.2007, 17:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

Репутация: 49
Всего: 76



DmitryHT
Вызываешь ZwQuerySystemInformation с параметром SYSTEMPROCESSESANDTHREADSINFORMATION.
Получаем структуру:
Код

  PSYSTEM_THREADS = ^SYSTEM_THREADS;
  SYSTEM_THREADS  = packed record
    KernelTime: LARGE_INTEGER;
    UserTime: LARGE_INTEGER;
    CreateTime: LARGE_INTEGER;
    WaitTime: ULONG;
    StartAddress: Pointer;
    UniqueProcess: DWORD;
    UniqueThread: DWORD;
    Priority: Integer;
    BasePriority: Integer;
    ContextSwitchCount: ULONG;
    State: Longint;
    WaitReason: Longint;
  end;

State и будет состояние потока. Возможные состояния вот:
Цитата

   THREADSTATE_RUNNING = 0x0001,
   THREADSTATE_STOPPED = 0x0002,
   THREADSTATE_FRESH   = 0x0003,
   THREADSTATE_DEAD    = 0x0004,
   THREADSTATE_FROZEN  = 0x0005


P.S. Метод не проверял пока, только теория, но функцию сделаю, т.к. и мне понадобиться smile
P.S.S. мб есть и другой более простое решение. 


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
Alix
Дата 28.9.2007, 08:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


L45
**


Профиль
Группа: Участник
Сообщений: 581
Регистрация: 4.5.2005
Где: Pskov/Spb

Репутация: 7
Всего: 23



Цитата
Alix, в твоем случае срабатывает только когда поток еще не запускался.
После первого запуска он становится Assigned даже не смотря на potok[i].FreeOnTerminate(True); 

Да. В моем случае надо в событии OnTerminate делать 
Код
potok[i] := nil; // i - который сейчас завершился

В помощь: как узнать, завершился ли поток и еще Многопоточность - как это делается в Дельфи. Не используйте потоки, не прочитав это

Это сообщение отредактировал(а) Alix - 28.9.2007, 08:21


--------------------
Знание только тогда знание, когда оно приобретено усилиями своей мысли, а не памятью (с) Л. Толстой
High tech. Low live. (с) Gardner Dozois
PM MAIL ICQ Skype   Вверх
Rennigth
Дата 28.9.2007, 10:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

Репутация: 49
Всего: 76



DmitryHT, функция:
Код

const

  SYSTEM_PROCESSES_AND_THREADS_INFORMATION = 5;

  NT_STATUS_SUCCESS              = DWord($00000000);
  NT_STATUS_ACCESS_DENIED        = DWord($C0000022);
  NT_STATUS_INFO_LENGTH_MISMATCH = DWord($C0000004);

  ThreadStateInitialized = $0000;
  ThreadStateReady = $0001;
  ThreadStateRunning = $0002;
  ThreadStateStandby = $0003;
  ThreadStateTerminated = $0004;
  ThreadStateWait = $0005;
  ThreadStateTransition = $0006;
  ThreadStateUnknown = $0007;  

type
  PSYSTEM_THREAD_INFORMATION = ^_SYSTEM_THREAD_INFORMATION;
  _SYSTEM_THREAD_INFORMATION  = packed record
    KernelTime: LARGE_INTEGER;
    UserTime: LARGE_INTEGER;
    CreateTime: LARGE_INTEGER;
    WaitTime: ULONG;
    StartAddress: Pointer;
    UniqueProcess: DWORD;
    UniqueThread: DWORD;
    Priority: Integer;
    BasePriority: Integer;
    ContextSwitchCount: ULONG;
    State: Longint;
    WaitReason: Longint;
  end;

  PSYSTEM_PROCESS_INFORMATION = ^_SYSTEM_PROCESS_INFORMATION;
  _SYSTEM_PROCESS_INFORMATION = packed record
    NextOffset: ULONG;
    ThreadCount: ULONG;
    Reserved1: array [0..5] of ULONG;
    CreateTime: FILETIME;
    UserTime: FILETIME;
    KernelTime: FILETIME;
    ModuleNameLength: WORD;
    ModuleNameMaxLength: WORD;
    ModuleName: PWideChar;
    BasePriority: ULONG;
    ProcessID: ULONG;
    InheritedFromUniqueProcessID: ULONG;
    HandleCount: ULONG;
    Reserved2 : array[0..1] of ULONG;
    PeakVirtualSize : ULONG;
    VirtualSize : ULONG;
    PageFaultCount : ULONG;
    PeakWorkingSetSize : ULONG;
    WorkingSetSize : ULONG;
    QuotaPeakPagedPoolUsage : ULONG;
    QuotaPagedPoolUsage : ULONG;
    QuotaPeakNonPagedPoolUsage : ULONG;
    QuotaNonPagedPoolUsage : ULONG;
    PageFileUsage : ULONG;
    PeakPageFileUsage : ULONG;
    PrivatePageCount : ULONG;
    ReadOperationCount : LARGE_INTEGER;
    WriteOperationCount : LARGE_INTEGER;
    OtherOperationCount : LARGE_INTEGER;
    ReadTransferCount : LARGE_INTEGER;
    WriteTransferCount : LARGE_INTEGER;
    OtherTransferCount : LARGE_INTEGER;
    ThreadInfo: array [0..0] of _SYSTEM_THREAD_INFORMATION;
  end;

function ZwQuerySystemInformation(ASystemInformationClass: Cardinal;
  ASystemInformation: Pointer; ASystemInformationLength: Cardinal;
  AReturnLength: PCardinal): Cardinal; stdcall; external 'ntdll.dll';


function GetNativeThreadInfo(AThreadID: DWORD): _SYSTEM_THREAD_INFORMATION;
var
  pSI, pSITemp: PSYSTEM_PROCESS_INFORMATION;
  hProcess: DWORD;
  dwSize: DWORD;
  dwOffSet: DWORD;
  i: Integer;
  lThreadIsFind: Boolean;
begin
  ZeroMemory(@Result, SizeOF(_SYSTEM_THREAD_INFORMATION));
  if AThreadID = 0 then Exit;

  dwSize := 0;
  lThreadIsFind := False;
  
  if ZwQuerySystemInformation(SYSTEM_PROCESSES_AND_THREADS_INFORMATION,
    nil, 0, @dwSize) <> NT_STATUS_INFO_LENGTH_MISMATCH then Exit;  (* Get Size *)

  pSI := VirtualAlloc(nil, dwSize, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
  if Assigned(pSI) then
  try
    if ZwQuerySystemInformation(SYSTEM_PROCESSES_AND_THREADS_INFORMATION,
      pSI, dwSize, @dwSize) = NT_STATUS_SUCCESS then
    begin
      pSITemp := pSI;
      repeat
        {$RANGECHECKS OFF}
        for i := 0 to pSITemp.ThreadCount - 1 do
        begin
          if pSITemp.ThreadInfo[i].UniqueThread = AThreadID then
          begin
            Result := pSITemp.ThreadInfo[i];
            lThreadIsFind := True;
            Break;
          end;
        end;
        {$RANGECHECKS ON}
        dwOffSet := pSITemp^.NextOffset;
        pSITemp := Pointer(DWORD(pSITemp) + dwOffSet);

        if lThreadIsFind then
          Break;
      until dwOffSet = 0;
    end;
  finally
    VirtualFree(pSI, 0, MEM_RELEASE);
  end;
end;



Использование:
Код

var
  lThreadInfo: _SYSTEM_THREAD_INFORMATION;
begin
  lThreadInfo := GetNativeThreadInfo(GetCurrentThreadId);
  case lThreadInfo.State of
    ThreadStateInitialized: Caption := 'Thread is ThreadStateInitialized';
    ThreadStateReady: Caption := 'Thread is ThreadStateReady';
    ThreadStateRunning: Caption := 'Thread is ThreadStateRunning';
    ThreadStateStandby: Caption := 'Thread is ThreadStateStandby';
    ThreadStateTerminated: Caption := 'Thread is ThreadStateTerminated';
    ThreadStateWait: Caption := 'Thread is ThreadStateWait';
    ThreadStateTransition: Caption := 'Thread is ThreadStateTransition';
    ThreadStateUnknown: Caption := 'Thread is ThreadStateUnknown';
  end;


Функция принимает ID потока. У Tthread есть св-во ThreadID, его и используй в качестве параметра.

Это сообщение отредактировал(а) Rennigth - 28.9.2007, 10:20


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
DmitryHT
Дата 28.9.2007, 14:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 31.8.2007

Репутация: нет
Всего: нет



Цитата

В моем случае надо в событии OnTerminate делат


спасибо помогло ;)
PM MAIL   Вверх
Delphist
Дата 31.10.2007, 12:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphist Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2145
Регистрация: 3.2.2004
Где: всегда в сети

Репутация: 2
Всего: 3



Цитата(Rennigth @  28.9.2007,  11:11 Найти цитируемый пост)
Функция принимает ID потока. У Tthread есть св-во ThreadID, его и используй в качестве параметра

Не очень быстрый вариант приходится перебирать все потоки, мне кажется должна быть готовая API-функция


--------------------
ProcessInfo 1-ая моя программа (аналог spyxx.exe с гораздо большим функц-ом - внедрение dll в адр. простр. процесса, перехват API-функций, разбор приложения на окна мн.др).
Когда-то давным-давно использовал это...
PM MAIL ICQ   Вверх
Alix
Дата 31.10.2007, 12:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


L45
**


Профиль
Группа: Участник
Сообщений: 581
Регистрация: 4.5.2005
Где: Pskov/Spb

Репутация: 7
Всего: 23



Сделать SuspendThread, если вернула -1, значит был работающим, иначе вернет предыдущее значение thread suspend count. После этой проверки сделать ResumeThread, чтобы вернуть все на место  smile 


--------------------
Знание только тогда знание, когда оно приобретено усилиями своей мысли, а не памятью (с) Л. Толстой
High tech. Low live. (с) Gardner Dozois
PM MAIL ICQ Skype   Вверх
Rennigth
Дата 31.10.2007, 13:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 21.6.2004
Где: Moscow

Репутация: 49
Всего: 76



Цитата(Delphist @  31.10.2007,  12:22 Найти цитируемый пост)
мне кажется должна быть готовая API-функция 
 
Готовая какая? По хендлу? Даже если бы такая и была, она действовала по такому же принципу, только еще бы и ID этого потока искала(могу, ошибаться, уж незнаю как сама винда получает доступ к своим системным объктам). Да и тем более если честно немогу придумать случая когда это нужно, если ты знаешь только хендл...
В любом случае, ни по ID, ни по хендлу вроде нету, уж документированной точно. 


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
Delphist
Дата 31.10.2007, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphist Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2145
Регистрация: 3.2.2004
Где: всегда в сети

Репутация: 2
Всего: 3



Цитата(Alix @  31.10.2007,  13:35 Найти цитируемый пост)
Сделать SuspendThread, если вернула -1, значит был работающим

значит был УЧИЧТОЖЕН, но SuspendThread не позволяет определить был ли поток приостановлен



--------------------
ProcessInfo 1-ая моя программа (аналог spyxx.exe с гораздо большим функц-ом - внедрение dll в адр. простр. процесса, перехват API-функций, разбор приложения на окна мн.др).
Когда-то давным-давно использовал это...
PM MAIL ICQ   Вверх
Alix
Дата 31.10.2007, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


L45
**


Профиль
Группа: Участник
Сообщений: 581
Регистрация: 4.5.2005
Где: Pskov/Spb

Репутация: 7
Всего: 23



Цитата(Delphist @  31.10.2007,  14:21 Найти цитируемый пост)
значит был УЧИЧТОЖЕН, но SuspendThread не позволяет определить был ли поток приостановлен

извиняюсь, это я обшибся, если работал, то вернет 0, если не существовал, вернет -1, если > 0, то был приостановлен


--------------------
Знание только тогда знание, когда оно приобретено усилиями своей мысли, а не памятью (с) Л. Толстой
High tech. Low live. (с) Gardner Dozois
PM MAIL ICQ Skype   Вверх
Delphist
Дата 31.10.2007, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphist Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2145
Регистрация: 3.2.2004
Где: всегда в сети

Репутация: 2
Всего: 3



Цитата(Alix @  31.10.2007,  14:45 Найти цитируемый пост)
извиняюсь, это я обшибся, если работал, то вернет 0, если не существовал, вернет -1, если > 0, то был приостановлен 

Я тут узнал, для того чтобы узнать существует ли поток или нет достаточно использовать GetExitCodeThread


--------------------
ProcessInfo 1-ая моя программа (аналог spyxx.exe с гораздо большим функц-ом - внедрение dll в адр. простр. процесса, перехват API-функций, разбор приложения на окна мн.др).
Когда-то давным-давно использовал это...
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0980 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.