Что было бы хорошим/лучшим для обеспечения безопасности потоков для объектов обратного вызова? В частности, я пытаюсь предотвратить деконструирование объекта обратного вызова, прежде чем все потоки будут завершены с ним.
Легко закодировать код клиента для обеспечения безопасности потоков, но я ищу способ, который немного более оптимизирован. Например, использование фабричного объекта для генерации объектов обратного вызова. Проблема заключается в отслеживании использования объекта обратного вызова.
Ниже приведен пример кода, который я пытаюсь улучшить.
class CHandlerCallback
{
public:
CHandlerCallback(){ ... };
virtual ~CHandlerCallback(){ ... };
virtual OnBegin(UINT nTotal ){ ... };
virtual OnStep (UINT nIncrmt){ ... };
virtual OnEnd(UINT nErrCode){ ... };
protected:
...
}
static DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
CHandler* phandler = (CHandler*)lpParameter;
phandler ->ThreadProc();
return 0;
};
class CHandler
{
public:
CHandler(CHandlerCallback * sink = NULL) {
m_pSink = sink;
// Start the server thread. (ThreadProc)
};
~CHandler(){...};
VOID ThreadProc(LPVOID lpParameter) {
... do stuff
if (m_pSink) m_pSink->OnBegin(..)
while (not exit) {
... do stuff
if (m_pSink) m_pSink->OnStep(..)
... do stuff
}
if (m_pSink) m_pSink->OnEnd(..);
};
private:
CHandlerCallback * m_pSink;
}
class CSpecial1Callback: public CHandlerCallback
{
public:
CSpecial1Callback(){ ... };
virtual ~CBaseHandler(){ ... };
virtual OnStep (UINT nIncrmt){ ... };
}
class CSpecial2Callback: public CHandlerCallback...
Затем код, который запускает все так, как показано ниже:
int main {
CSpecial2Callback* pCallback = new CSpecial2Callback();
CHandler handler(pCallback );
// Right now the client waits for CHandler to finish before deleting
// pCallback
}
Благодарю!
Если вы используете С++ 11, вы можете использовать интеллектуальные указатели, чтобы поддерживать объект до тех пор, пока последняя ссылка на объект не исчезнет. См. Shared_pointer. Если вы не в С++ 11, вы можете использовать форсированную версию. Если вы не хотите включать эту библиотеку и не находитесь в С++ 11, вы можете прибегнуть к сохранению внутреннего подсчета потоков с использованием этого объекта и уничтожить объект, когда это число достигнет 0. Обратите внимание, что попытка отслеживать счетчик самостоятельно может быть затруднено, так как вам потребуются атомарные обновления для счетчика.
shared_ptr<CSpecial2Callback> pCallback(new CSpecial2Callback());
CHandler handler(pCallback); // You'll need to change this to take a shared_ptr
... //Rest of code -- when the last reference to
... //pCallback is used up it will be destroyed.
QSharedPointer<>
но я думаю, что это не вариант здесь.