Как убить поток снаружи

Тема в разделе "WASM.WIN32", создана пользователем provocateur, 6 ноя 2008.

  1. provocateur

    provocateur Member

    Публикаций:
    0
    Регистрация:
    5 дек 2006
    Сообщения:
    118
    Создаю несколько потоков с помощью CreateThread. Внутри каждого идет обращение к сайту (в каждом потоке свой сайт). Если пользователю надоело ждать, он нажимает "Стоп". Поиск должен остановится.
    Сначала у меня сайты опрашивались последовательно, при нажатии на "Стоп" переменной присваивалось специальное значение, а внутри потока эта переменная постоянно проверялась и поток отключался, если появлялось нужное значение. Но был и минус: приходилось ждать завершения текущего действия (InternetConnect, HttpOpenRequest, HttpSendRequest, InternetReadFile). Т.е. в любом случае была задержка, иногда довольно большая.
    Теперь хочется сделать нормально. СloseHandle не работает (хотя я так и не понял должен ли он тут срабатывать).

    PS
    Нормально ли таким жестоким способом прерывать InternetConnect, или же нужно дожидаться завершения текущего действия и делать InternetCloseHandle для каждого этапа?
     
  2. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    если процессы разные - не нада. убить процесс см. TerminateProcess
    а если потоки, и процесс один - лучше подожди, т.к. при очень длительной работе весь этот хлам может скапливаться многократно
     
  3. provocateur

    provocateur Member

    Публикаций:
    0
    Регистрация:
    5 дек 2006
    Сообщения:
    118
    max7C4, да-да процесс один. Действительно будет скапливаться эта муть. Но сайты иногда с таким скрипом отвечают, плюс скорость соединения далеко не всегда приемлемая. эх.

    а грохнуть поток как-то снаружи можно?
     
  4. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    TerminateThread ?
     
  5. provocateur

    provocateur Member

    Публикаций:
    0
    Регистрация:
    5 дек 2006
    Сообщения:
    118
    Вот блин! Точно! А в описании CreateThread среди ссылок на связанные функции ничего такого нету :dntknw:

    GoldFinch, а вы сами, что посоветуете, грохать поток сразу или ждать завершения текущей операции и закрывать интернет соединение?
     
  6. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    provocateur
    а кто его знает хорошо это или плохо...
    может стоит посмотреть в сторону асинхронного режима?
     
  7. Partner

    Partner Павел

    Публикаций:
    0
    Регистрация:
    28 фев 2008
    Сообщения:
    917
    Адрес:
    Los Angeles
    Убивать поток снаружи - это крайняя мера. Возможны утечки ресурсов, незакрытие хендлов etc
     
  8. provocateur

    provocateur Member

    Публикаций:
    0
    Регистрация:
    5 дек 2006
    Сообщения:
    118
    GoldFinch, что вы имеете ввиду?

    Partner, полностью согласен. Незакрытыми остаются WinInet соединения :dntknw:
     
  9. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    InternetSetStatusCallback
     
  10. provocateur

    provocateur Member

    Публикаций:
    0
    Регистрация:
    5 дек 2006
    Сообщения:
    118
    GoldFinch, или я в английском не силен, или просто не понимаю :) какая разница как дожидаться окончания выполнения функции. У меня и так для каждого соединения свой поток, внутри него я комфортно получаю данные от InternetReadFile. А что мне дает использование InternetSetStatusCallback?
     
  11. Partner

    Partner Павел

    Публикаций:
    0
    Регистрация:
    28 фев 2008
    Сообщения:
    917
    Адрес:
    Los Angeles
    http://msdn.microsoft.com/en-us/library/aa383892
     
  12. SlyBit

    SlyBit New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2008
    Сообщения:
    43
    Может стоит попробывать функции Winsock? Там задержек не замечал.
     
  13. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    Partner прав. асинхронная работа тут рулит. при использовании асинхронного режима не обязательно ждать завершения текущего действия, его можно тупо прервать.
     
  14. provocateur

    provocateur Member

    Публикаций:
    0
    Регистрация:
    5 дек 2006
    Сообщения:
    118
    SlyBit, довольно сложно на сокетах городить огород. непонятно куда денутся задержки: соединиться нужно, получить данные нужно. скорость интернет соединения у всех разная.

    Partner, Freeman, буду читать. Не вся сразу дается.
     
  15. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    Freeman
    +1
    имеется ввиду, что ты попросил систему, и система за тебя сама присоединится, подождет данные и, как данные будут приняты, сообщит тебе об этом, но такое действие всегда можно попросить прервать.
    P.S. Извиняюсь за язык для домохозяек, но нормальное объяснение было не понято!
     
  16. protein

    protein New Member

    Публикаций:
    0
    Регистрация:
    1 мар 2006
    Сообщения:
    17
    Адрес:
    Russia
    Если я правильно представил себе ситуацию, то чем плохо, что идет медленное рассоединение в потоке. Если существует UI, с которым взаимодействует пользователь, то мы просто эти элементы немедленно скрываем от юзера, а рассоединение спокойно идет в фоне программы в своем потоке.
     
  17. provocateur

    provocateur Member

    Публикаций:
    0
    Регистрация:
    5 дек 2006
    Сообщения:
    118
    protein, так и происходит.
    просто я пока не сделал флаг, который бы правильно работал. если быстро нажать стоп и старт, то получится, что новое соединение появится, а старое продолжит работать (поток увидит, что флаг включен, и не будет знать что его выключали).
    уже примерно знаю как это сделать, надо только еще хорошо подумать. похоже, что нужно создавать переменную для каждого соединения, а не использовать один и тот же участок памяти.
     
  18. Twister

    Twister New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    720
    Адрес:
    Алматы
    Механизм примитивен. Я делаю примерно так:
    Код (Text):
    1. var
    2.   hTaskAnalyzeThread: DWORD;
    3.   bStopTaskAnalyze: boolean;
    4.  
    5. procedure TaskAnalyzeThread(pvoid: pointer); stdcall;
    6. begin
    7. while not bStopTaskAnalyze do
    8.   begin
    9.   // Тут действа
    10.   Sleep(500);
    11.   end;
    12. // Тут закрытие всего того, с чем работает поток
    13. ExitThread(0);
    14. end;
    15.  
    16. procedure taskStartAnalyze();
    17. var
    18.   dwThreadId: DWORD;
    19. begin
    20. bStopTaskAnalyze := false;
    21. hTaskAnalyzeThread := CreateThread(nil, 0, @TaskAnalyzeThread, nil, 0, dwThreadId);
    22. end;
    23.  
    24. procedure taskStopAnalyze();
    25. begin
    26. if hTaskAnalyzeThread <> 0 then
    27.   begin
    28.   bStopTaskAnalyze := true;
    29.   if WaitForSingleObject(hTaskAnalyzeThread, 500) = WAIT_TIMEOUT then
    30.     TerminateThread(hTaskAnalyzeThread, 0);
    31.   end;
    32. end;
     
  19. provocateur

    provocateur Member

    Публикаций:
    0
    Регистрация:
    5 дек 2006
    Сообщения:
    118
    Twister, у меня, в целом, так же сделано. отличие только в нюансах. работает отлично если пользователь жмет "Старт" , потом "Стоп". Только поток не грохается TerminateThread, а выходит сам ExitThread (внутри пропускается все что можно, если флаг сменился). Из-за этого возникает проблема: т.к. поток останавливается не мгновенно (на некоторых интернет соединениях это просто нереально), то при последующем старте, внутри потока, который еще не закончился, при проверке флага оказывается, что нужно нормально работать, а не останавливаться.
    У меня свой флаг на каждый сайт/страницу. Похоже нужно создавать переменную для флага на каждый поток, тогда только получится решить проблему.
     
  20. Twister

    Twister New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    720
    Адрес:
    Алматы
    Тебе нужно завести еще один флаг, который будет говорить об удачном завершении потока (не важно, сам он завершился или был убит снаружи) и не давать снова запускаться потокам, пока "флак удачного завершения" не будет установлен. Идеальным решением будет мьютекс.