Вам было бы лучше синхронизировать потоки через какой-либо объект синхронизации (событие, блокировку, мьютексы, семафор, критический раздел, что угодно ...) или такие, чтобы основной поток мог ждать рабочего потока.
Здесь у вас есть условие гонки: что делать, если флаг выключения поднимается сразу после if
Состояние оценивается и до выполнения операции БД?
Вот иллюстрация с мьютексами как известный примитив синхронизации, но есть лучшие способы.
Главная нить:
int main() {
... wait for signal to exit the app
// the DB operations are running on another thread
...
// assume that we start shutdown here
// also assume that there is some global mutex g_mutex
// following line blocks if mutex is locked in worker thread:
std::lock_guard<std::mutex> lock(g_mutex);
Cleanup(); // should also ensure that worker is stopped
}
Рабочий поток:
void MyWorkerThread::RunMethod()
{
{
std::lock_guard<std::mutex> lock(g_mutex);
DoSomethingOnDB();
}
// some other, non locked execution which doesn't prevent
// main thread from exiting
...
{
std::lock_guard<std::mutex> lock(g_mutex);
DoSomethingMoreOnDB();
}
}
, как, очевидно, вы не хотите, чтобы повторить все блокировки, вы должны обернуть его:
void MyWorkerThread::RunMethod()
{
Execute(DoSomethingOnDB);
...
Execute(DoSomethingMoreOnDB);
}
void MyWorkerThread::Execute(DatabaseFn fn)
{
std::lock_guard<std::mutex> lock(g_mutex);
fn();
}
но использование блокировки не будет таким же? может ли GetShutdownFlag восприниматься как единое целое? – d3r0n
нет, поскольку блокировка может помешать основному потоку даже входить в выключение, если выполняется операция БД. В отличие от 'if's, блокировки блокировки блокировки, если блокировка уже выполнена (здесь здесь подразумевается примитив sync вообще). Затем только после того, как блокировка будет выпущена в другом потоке, первый поток будет продолжен. –
Спасибо, это действительно хорошее решение для обработки потока db, но не отвечает на вопрос. – d3r0n