Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: sergek от Декабрь 22, 2022, 10:01



Название: [Решено] Глобальная переменная в потоках
Отправлено: sergek от Декабрь 22, 2022, 10:01
Коллеги,
вопрос про азы многопотокового программирования. Думаю, что ответ простой и очевидный ))
Есть глобальная булевая переменная COptions::profilerIsActive.
Переменная может изменяться из разных потоков с использованием мьютекса, например:
Код
C++ (Qt)
{
   QMutexLocker locker(&mutex);
   COptions::profilerIsActive = true;
...
}
 
Она используется в качестве флага для эмитирования сигнала вот так, без блокировки:
Код
C++ (Qt)
   if(COptions::profilerIsActive) {
       emit profilerSig(1, vars.unitId, requestId, QDateTime::currentMSecsSinceEpoch(), vars.hasError(), queueLength());
   }
 
Вопрос: если в момент чтения переменной выполняется ее изменение, может ли это привести к краху программы? То, что я могу прочитать недостоверное значение, меня не волнует - на следующем цикле прочту истинное значение и запущу или остановлю испускание сигнала.



Название: Re: Глобальная переменная в потоках
Отправлено: sergek от Декабрь 22, 2022, 10:26
Добавлю еще вопрос: как оценить ресурсоемкость мьютекса на чтение? В первую очередь, его быстродействие.


Название: Re: Глобальная переменная в потоках
Отправлено: kambala от Декабрь 22, 2022, 11:05
краха не будет

для производительности можно попробовать заменить мьютекс на QAtomicInteger<bool>, если это подойдет


Название: Re: Глобальная переменная в потоках
Отправлено: sergek от Декабрь 22, 2022, 12:06
Да, я об этом думал. Но мне не критична целостность этой переменной, поэтому не стал усложнять. Спасибо.


Название: Re: Глобальная переменная в потоках
Отправлено: qate от Декабрь 22, 2022, 22:56
если достоверность profilerIsActive не сильно важна, то мутекс вообще можно убрать

и чтобы два раз не вставать, тут https://www.youtube.com/watch?v=dFEBrGJ8j2w&list=PL3BR09unfgcgJPQZKaacwzGmcXMtEA-19&index=20 умный дядька Konstantin Vladimirov как раз про потоки вещает


Название: Re: Глобальная переменная в потоках
Отправлено: Авварон от Декабрь 23, 2022, 10:55
если достоверность profilerIsActive не сильно важна, то мутекс вообще можно убрать


нельзя
если не важно значение то это томик с relaxed memory order.
чтение без синхронизации - ub


Название: Re: Глобальная переменная в потоках
Отправлено: sergek от Декабрь 23, 2022, 13:28
Уточню.
если достоверность profilerIsActive не сильно важна, то мутекс вообще можно убрать
Нельзя. Потому что одновременная запись - это, как уже сказано, UB. Неопределенность я понимаю в широком смысле: если несколько потоков пишут туда true, то состояние переменной может оказаться каким угодно, например, false (хотя откуда оно там возьмется? :)).
А вот при чтении, в моем конкретном случае, UB не сильно беспокоит. Ну один раз я прочту не то, что на самом деле должно быть в переменной, это приведет к тому, что либо будет пропущен сигнал или, наоборот, будет эмитирован лишний. Именно в моей задаче это не принципиально.
Спасибо всем.


Название: Re: Глобальная переменная в потоках
Отправлено: Авварон от Декабрь 23, 2022, 15:57
Ub в данном случае может вылиться в if (false) или if (true)


Название: Re: Глобальная переменная в потоках
Отправлено: qate от Декабрь 23, 2022, 18:01
Ub в данном случае может вылиться в if (false) или if (true)

а т.к. для ТС не сильно важно это, то можно


Название: Re: Глобальная переменная в потоках
Отправлено: Авварон от Декабрь 27, 2022, 00:59
Ub в данном случае может вылиться в if (false) или if (true)

а т.к. для ТС не сильно важно это, то можно


не важно не удалит ли его код компилятор? тогда зачем этот код нужен?


Название: Re: Глобальная переменная в потоках
Отправлено: sergek от Декабрь 27, 2022, 09:16
не важно не удалит ли его код компилятор? тогда зачем этот код нужен?
Это единственное, что меня напрягает. Но все работает...
А если использовать волшебное "volatile", этого достаточно?


Название: Re: Глобальная переменная в потоках
Отправлено: Авварон от Декабрь 30, 2022, 11:54
достаточно использовать волшебный atomic_bool


Название: Re: Глобальная переменная в потоках
Отправлено: sergek от Декабрь 30, 2022, 13:22
Как я уже упомянул, синхронизация при чтении меня не особо заботит - процесс циклический и пропуск или, наоборот, лишний сигнал не помешает. Нужно лишь включить или выключить профайлер.
Поэтому atomic_bool по сравнению с volatile мне видится чересчур "достаточным" ;)
Впрочем, простая с виду тема затянулась, и это чревато тем, что не все начинают заглядывать, с чего все начиналось.