Я бы хотел, чтобы мой поток закрывался более изящно, поэтому я пытаюсь реализовать простой механизм сигнализации. Я не думаю, что я хочу полностью управляемый событиями поток, поэтому у меня есть рабочий с методом, чтобы полностью остановить его, используя критический раздел Monitor
(эквивалентно С# lock
, я считаю):
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
, потому что чтение/запись может быть не атомарным. Я думаю, что этот флаг с одним выстрелом является исключением, которое доказывает правило?