Я бы хотел, чтобы мой поток завершался более изящно, поэтому я пытаюсь реализовать простой механизм сигнализации. Я не думаю, что мне нужен поток, полностью управляемый событиями, поэтому у меня есть рабочий с методом постепенной остановки его с помощью критической секции Monitor
(эквивалент блокировки C #
Я считаю ):
DrawingThread.h
class DrawingThread {
bool stopRequested;
Runtime::Monitor CSMonitor;
CPInfo *pPInfo;
//More..
}
DrawingThread.cpp
void DrawingThread::Run() {
if (!stopRequested)
//Time consuming call#1
if (!stopRequested) {
CSMonitor.Enter();
pPInfo = new CPInfo(/**/);
//Not time consuming but pPInfo must either be null or constructed.
CSMonitor.Exit();
}
if (!stopRequested) {
pPInfo->foobar(/**/);//Time consuming and can be signalled
}
if (!stopRequested) {
//One more optional but time consuming call.
}
}
void DrawingThread::RequestStop() {
CSMonitor.Enter();
stopRequested = true;
if (pPInfo) pPInfo->RequestStop();
CSMonitor.Exit();
}
Я понимаю (по крайней мере, в Windows) Monitor
/ lock
- это наименее затратный примитив синхронизации потоков, но я стараюсь избегать чрезмерного использования. Должен ли я упаковывать каждое чтение этого логического флага? Он инициализируется значением false и только один раз устанавливается в значение true, когда запрашивается остановка (если он запрашивается до завершения задачи).
Мои наставники посоветовали защищать даже bool
, потому что чтение / запись не могут быть атомарными. Я думаю, что этот одноразовый флаг - исключение, подтверждающее правило?