Поток как член класса
Может кто чего посоветует, или я чего не так понимаю в использовании потоков внутри класса?
Такая проблема, внутри класса надо запустить поток с потоковой функцией, являющейся членом класса. В потоковой функции используются переменные объекта и вызываются другие члены класса. Чтобы запустить потоковую функцию, внутри класса ее надо объявлять статической, со всеми вытекающими последствиями - надо объявлять статическими все используемые переменные и функции. Пока у нас один объект класса - все бы хорошо, а когда их много - начинаются проблемы.
Может кто чего посоветует, или я чего не так понимаю в использовании потоков внутри класса?
Во-первых, выражение "внутри класса надо запустить поток" неверно по многим причинам.
Во-вторых, в аргументах, передаваемых методу создающему поток (CreateThread или др.), не просто так присутствует "параметр передаваемый в потоковую процедуру" ("The parameter to be passed to the thread procedure"). Вот и передавайте в него указатель на экземпляр класса.
CreateThread(NULL, 0, &ThreadProc, this, 0, &dwThreadID);
class A
{
public:
A () : m_hThread (NULL), m_A (0), m_B (0) {}
virtual ~A();
bool RunThread (void);
static unsigned int __stdcall Thread (void*);
protected:
virtual unsigned int CoolThread (void);
virtual bool MyImpl (void) { return TRUE; }
// Другие методы
protected:
HANDLE m_hThread;
int m_A;
int m_B;
// И т.д.
};
// Определение
unsigned int __stdcall A::Thread (void* p)
{
// Здесь можешь воспользоваться cast'ом
// будет более читабельно.
return ((A*)p) -> CoolThread ();
}
unsigned int A::CoolThread ()
{
// Работаем с переменными и методами класса,
// например:
m_A = 2;
m_B = 1;
MyImpl ();
// Другие действия
return 0;
}
bool A::RunThread ()
{
unsigned int res = 0;
// Совет: Никогда не пользуй CreateThread, вместо
// этого используй _beginthreadex
m_hThread = (HANDLE)_beginthreadex (NULL, 0, Thread, this, 0, &res);
if (!m_hThread)
assert (0);
}
A::~A()
{
if (m_hThread)
{
// Уничтожение потока
DWORD res = 0;
res = ::WaitForSingleObject (m_hThread, 1000);
switch (res)
{
case WAIT_OBJECT_0:
break;
case WAIT_TIMEOUT:
::TerminateThread (m_hThread, -1);
break;
default:
assert (0);
}
::CloseHandle (m_hThread);
}
}
Во-первых, выражение "внутри класса надо запустить поток" неверно по многим причинам.
Во-вторых, в аргументах, передаваемых методу создающему поток (CreateThread или др.), не просто так присутствует "параметр передаваемый в потоковую процедуру" ("The parameter to be passed to the thread procedure"). Вот и передавайте в него указатель на экземпляр класса.
CreateThread(NULL, 0, &ThreadProc, this, 0, &dwThreadID);
Окей, про "поток внутри класса" согласен, но я же написал, что потоковой функцией должен быть член класса, и поток вызывается из другого члена класса. То бишь все операции с потоком заключены в класс, это я и имел ввиду под "потоком буквоедство прям какое-то, чуть где неточно выразишься, сразу носом тыкают :)
CreateThread вызывается внутри класса (из другой функции- члена класса), в этом и была вся проблема.
Я сделал через вызов через AfxBeginThread
все реализовано следующим образом:
Объявление процедур:
void threading();
вызов потока:
реализация функций:
{
CMyClass * me = (CMyClass *)p;
me->threading();
return 0;
}
void CMyClass::threading()
{
// код
}
решение взято с codeguru
Все работает великолепно, то для чего делалось разделение на потоки выполняется без задоринки.
Однако есть одна вещь, которая меня настораживает - когда я просматриваю потоки в системе (с помощью ProcessExplorer от System Internals), у меня виден только один основной поток моего приложения, второго потока не видно. Что бы это значило?
решение взято с codeguru
Все работает великолепно, то для чего делалось разделение на потоки выполняется без задоринки.
Это решение - частный вариант того, о чем я говорил.
Однако есть одна вещь, которая меня настораживает - когда я просматриваю потоки в системе (с помощью ProcessExplorer от System Internals), у меня виден только один основной поток моего приложения, второго потока не видно. Что бы это значило?
Это возможно в нескольких случиях:
1) поток не был создан, ты проверяешь успешность создания потока?
2) поток уже завешил свое существование ко времени перебора потоков. Как ты задаешь время существования этого потока?
Это возможно в нескольких случиях:
1) поток не был создан, ты проверяешь успешность создания потока?
2) поток уже завешил свое существование ко времени перебора потоков. Как ты задаешь время существования этого потока?
Поток создается рабочий, завершается по выходу из потоковой функции. В потоке идет обработка данных с внешнего устройства и управление им. Т.е. когда поток запущен - крутится движок, когда поток завершается - движок, есс-но, крутится не может. Я смотрю на созданные потоки когда движок крутится.
Я смотрю правда, когда проект запущен из VS. Надо попробовать откомпилированную программу посмотреть.