#c #visual-studio #winapi #threadpool #atl
#c #visual-studio #winapi #threadpool #atl
Вопрос:
Допустим, у вас есть какой-то класс, и вы хотите вызвать некоторые из его методов в фоновом потоке. Это то, что меня интересует, и я подумал CThreadPool
, что было бы неплохо использовать для этого. Мне было интересно, использовал ли кто CThreadPool
-нибудь раньше вызовы методов for.
Итак, вот что я настроил. На основе этого примера от Microsoft я создал абстрактный класс «task» (который я обозначил как интерфейс), а также рабочий класс:
class ITask
{
public:
virtual void DoTask(LPVOID, LPOVERLAPPED) = 0;
};
class CWorker
{
public:
typedef DWORD_PTR RequestType;
BOOL Initialize(LPVOID)
{
return TRUE;
}
void Execute(RequestType dw, LPVOID pvParam, LPOVERLAPPED pOverlapped) throw()
{
ITask* pTask = (ITask*)(DWORD_PTR)dw;
pTask->DoTask(pvParam, pOverlapped);
}
void Terminate(LPVOID)
{
}
};
Затем в моем основном классе я, по сути, делаю это:
class MyClass
{
public:
MyClass()
{
m_threadpool.Initialize(this, NUM_OF_THREADS_DESIRED);
}
~MyClass()
{
m_threadpool.Shutdown();
}
private:
CThreadPool<CWorker> m_threadpool;
class : public ITask
{
public:
void DoTask(LPVOID pvParam, LPOVERLAPPED)
{
MyClass* pObj = (MyClass*)pvParam;
pObj->MethodToCallOnBackgroundThread();
}
} m_task;
void MethodForQueuing()
{
m_threadpool.QueueRequest((CWorker::RequestType)amp;m_task);
}
void MethodToCallOnBackgroundThread()
{
// Do something
}
};
Кажется, это работает. Одним из недостатков является то ITask
, что для каждого метода, для которого вы хотели бы использовать threadpool, требуется объявление нового производного класса, но, по-видимому, так работает пример Microsoft. Я предполагаю, что другим подходом было бы создать более общий объект task, а затем передать перечисление или что-то в этом роде, которое можно использовать для оператора switch в методе класса. В любом случае, кто-нибудь сталкивался с этой ситуацией, и если да, есть ли у вас какие-либо данные?
Комментарии:
1. Если нет конкретной причины, по которой вы хотите написать такой код начала 2000-х годов излишне специфичным для платформы способом, я бы посоветовал вам либо просто использовать
std::async
, либо, по крайней мере, упаковывать свои задачи вstd::function
объекты вместо того, чтобы писать каждый конкретный подкласс вручную.2. Хорошо, спасибо. Я проверю это. Это в контексте проекта ATL, поэтому я и рассматривал
CThreadPool
.3. использовать использовать системный пул и
QueueUserWorkItem
илиCreateThreadpoolWork