Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> _beginthreadex: как правильно убить поток? Т.е. необходимо грубое завершение треда  
V
    Опции темы
Alca
Дата 18.5.2009, 14:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



_beginthreadex: как правильно убить поток? Т.е. необходимо грубое завершение треда (KillThread).

MSDN:
Цитата

You can call _endthread or _endthreadex explicitly to terminate a thread; however, _endthread or _endthreadex is called automatically when the thread returns from the routine passed as a parameter. Terminating a thread with a call to endthread or _endthreadex helps to ensure proper recovery of resources allocated for the thread.

Т.е. рекомендуется использовать _endthreadex вместо других вариантов (TerminateThread, ...).
Код

#include <windows.h>
#include <iostream>
#include <string>
#include <process.h>

using namespace std;
//---------------------------------------------------------------------------
UINT WINAPI thread(LPVOID) {
    for (int i = 0; i < 100; i ++) {
        cout << "Working..." << endl;
        ::Sleep(1000);
    }

    return 0;
}
//---------------------------------------------------------------------------
int main() {
    HANDLE  hThread  = INVALID_HANDLE_VALUE;
    UINT    IDThread = 0;

    // создаем поток для подсчета лексем
    hThread = (HANDLE) _beginthreadex(NULL, 0, thread, 0, 0, &IDThread);
    if (INVALID_HANDLE_VALUE == hThread) {
        return ::GetLastError();
    }
    ::Sleep(2000);

    //::TerminateThread(m_hThread, 0);
    _endthreadex(- 1);

    ::WaitForSingleObject(hThread, INFINITE);
    ::CloseHandle(hThread);

    cout << "End..." << endl;

    system("pause");
    return 0;
}
//---------------------------------------------------------------------------

Поток не убивается.


--------------------
PM WWW ICQ Skype Jabber   Вверх
Lazin
Дата 18.5.2009, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



endthreadex завершает тот поток, в котором вызвана, а строчка 
Цитата(Alca @  18.5.2009,  14:56 Найти цитируемый пост)
however, _endthread or _endthreadex is called automatically when the thread returns from the routine passed as a parameter

говорит нам о том, что это эквивалентно return smile 

Код

#include <windows.h>
#include <iostream>
#include <string>
#include <process.h>
using namespace std;

volatile bool run = true;
//---------------------------------------------------------------------------
UINT WINAPI thread(LPVOID) 
{
    for (int i = 0; i < 100; i ++) {
    if (!run ) return 0;
        cout << "Working..." << endl;
        ::Sleep(1000);
    }
    return 0;
}
//---------------------------------------------------------------------------
int main() {
    HANDLE  hThread  = INVALID_HANDLE_VALUE;
    UINT    IDThread = 0;
    // создаем поток для подсчета лексем
    hThread = (HANDLE) _beginthreadex(NULL, 0, thread, 0, 0, &IDThread);
    if (INVALID_HANDLE_VALUE == hThread) {
        return ::GetLastError();
    }
    ::Sleep(2000);
    //::TerminateThread(m_hThread, 0);
    run = false;//end thread..
    ::WaitForSingleObject(hThread, INFINITE);
    ::CloseHandle(hThread);
    cout << "End..." << endl;
    system("pause");
    return 0;
}
//---------------------------------------------------------------------------

PM MAIL Skype GTalk   Вверх
Alca
Дата 18.5.2009, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Значит надо прибивать функцией TerminateThread....

Добавлено через 12 минут и 4 секунды
Код

/***
*_endthreadex() - Terminate the calling thread
*
*Purpose:
*
*Entry:
*       Thread exit code
*
*Exit:
*       Never returns!
*
*Exceptions:
*
*******************************************************************************/

void __cdecl _endthreadex (
        unsigned retcode
        )
{
        _ptiddata ptd;           /* pointer to thread's _tiddata struct */

        /*
         * Call fp termination, if necessary
         */
#ifdef CRTDLL
        _fpclear();
#else  /* CRTDLL */
        if (_FPmtterm != NULL &&
            _IsNonwritableInCurrentImage((PBYTE)&_FPmtterm))
        {
            (*_FPmtterm)();
        }
#endif  /* CRTDLL */

        ptd = _getptd_noexit();

        if (ptd) {
            /*
             * Free up the _tiddata structure & its subordinate buffers
             *      _freeptd() will also clear the value for this thread
             *      of the FLS variable __flsindex.
             */
            _freeptd(ptd);
        }

        /*
         * Terminate the thread
         */
        ExitThread(retcode);

}

А почему ExitThread не срабатывает?


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alca
Дата 18.5.2009, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата

ExitThread Function


Ends the calling thread.
Syntax
C++
Код

VOID WINAPI ExitThread(
  __in  DWORD dwExitCode
);

Parameters
dwExitCode [in] 

The exit code for the thread.
Return Value

This function does not return a value.
Remarks

ExitThread is the preferred method of exiting a thread in C code. However, in C++ code, the thread is exited before any destructors can be called or any other automatic cleanup can be performed. Therefore, in C++ code, you should return from your thread function.

Что значит "Ends the calling thread."?


--------------------
PM WWW ICQ Skype Jabber   Вверх
GoldFinch
Дата 18.5.2009, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



ExitThread убивает текущий поток

Добавлено через 1 минуту и 37 секунд
тема про убийство потока недавно уже была, зачем еще одна?
используй SetThreadContext чтоб передать управление на _endthread
PM MAIL ICQ   Вверх
Alca
Дата 18.5.2009, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата

ExitThread убивает текущий поток

т.е. убивает тот поток в котором он вызван (мысли вслух). 


--------------------
PM WWW ICQ Skype Jabber   Вверх
Lazin
Дата 18.5.2009, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



Цитата(GoldFinch @  18.5.2009,  15:52 Найти цитируемый пост)
используй SetThreadContext чтоб передать управление на _endthread

деструкторы не отработают
PM MAIL Skype GTalk   Вверх
GoldFinch
Дата 18.5.2009, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



Lazin, 
они при _endthread полюбому не отработают, если они есть.

тогда надо искать место на котором виснет поток и передавать управление сразу после него, например через исключение
Код

try{
  foo(); //на этой функции поток может повиснуть
}catch(...)
  //тут мы окажемся например если обнулить eip
};


Это сообщение отредактировал(а) GoldFinch - 18.5.2009, 17:32
PM MAIL ICQ   Вверх
andrew_121
Дата 18.5.2009, 18:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


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

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



GoldFinch, И какой аргумент в этом случае получит catch ?


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
Lazin
Дата 18.5.2009, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



почему-бы не воспользоваться нормальным способом завершения потоков? мне почему-то за все время работы не приходилось страдать подобной ерундой
Цитата(GoldFinch @  18.5.2009,  17:32 Найти цитируемый пост)
//тут мы окажемся например если обнулить eip

с чего это вдруг?

Добавлено через 37 секунд
Цитата(andrew_121 @  18.5.2009,  18:45 Найти цитируемый пост)
И какой аргумент в этом случае получит catch ?


Цитата(GoldFinch @  18.5.2009,  17:32 Найти цитируемый пост)
catch(...)


lol, ты так шутишь? smile

Добавлено через 3 минуты и 19 секунд
GoldFinch, мне интересно, где ты прочитал о том, что проект собирается в VS и компилируется с опцией /Eha?

Добавлено через 4 минуты и 40 секунд
в любом случае подобные финты это UB, как программа будет работать... одному богу известно
PM MAIL Skype GTalk   Вверх
GoldFinch
Дата 18.5.2009, 21:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



Цитата(Lazin @  18.5.2009,  19:48 Найти цитируемый пост)
что проект собирается в VS и компилируется с опцией /Eha?

в конце концов, можно руками поставить SEH
Код

int recv_wrap(  ....   ) {
      __asm{
            pusha
            call skip_handler
            //SEH handler
            mov eax,[esp+0x0C] //context
            mov [eax+0xB8],offset finally //eip
            xor eax,eax
            ret
skip_handler:
            push dword ptr fs:[0]
            mov fs:[0],esp 
      };
      int r=recv(s,&buf,10000,MSG_WAIT); //здесь поток может повиснуть
finally:
      __asm{
            mov esp,fs:[0]
            pop dword ptr fs:[0]
            pop eax
            popa
      };
}


и никакого UB тут нет, для системы это нормально (а система вполне конкретная - windows)

Это сообщение отредактировал(а) GoldFinch - 18.5.2009, 21:16
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




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


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

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