Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: Igors от Январь 24, 2012, 14:12



Название: Нужна ли блокировка ?
Отправлено: Igors от Январь 24, 2012, 14:12
Добрый день

Такой кусочек выполняется 2 или более нитками
Код
C++ (Qt)
if (Test(data))
data->mFlag |= 1;
 
Нужно ли защищать установку бита мутексом?

Спасибо


Название: Re: Нужна ли блокировка ?
Отправлено: mutineer от Январь 24, 2012, 14:30
Если внутри Test(data) читается mFlag, то нужно обязательно. Причем весь if


Название: Re: Нужна ли блокировка ?
Отправлено: pastor от Январь 24, 2012, 17:21
Также нет гарантий того, что "data->mFlag |= 1;" атомарна. Можно перейти на использование QAtomicInt. Также обрати внимание на QReadWriteLock


Название: Re: Нужна ли блокировка ?
Отправлено: Igors от Январь 24, 2012, 17:26
Также нет гарантий того, что "data->mFlag |= 1;" атомарна.
Она просто не атомарна  :)  Ну и что? Чем мне это грозит?


Название: Re: Нужна ли блокировка ?
Отправлено: pastor от Январь 24, 2012, 17:48
Цитировать
Она просто не атомарна

Зависит от типа mFlag, компилятора, уровня оптимизации

Цитировать
Ну и что? Чем мне это грозит?

Одновременное выполение инструкций "operator|=". Причем для одного потока выполенние инструкций может только начаться, а для другого еще не заверщиться.


Название: Re: Нужна ли блокировка ?
Отправлено: mutineer от Январь 24, 2012, 17:50
Цитировать
Ну и что? Чем мне это грозит?

Одновременное выполение инструкций "operator|=". Причем для одного потока выполенние инструкций может только начаться, а для другого еще не заверщиться.

В принципе результат выполнения в любом случае будет один и тот же)))


Название: Re: Нужна ли блокировка ?
Отправлено: pastor от Январь 24, 2012, 17:59
В принципе результат выполнения в любом случае будет один и тот же)))

Если нет модификации mFlag в другом месте, то пожалуй соглашусь в контексте данного примера )


Название: Re: Нужна ли блокировка ?
Отправлено: Igors от Январь 24, 2012, 18:11
Зависит от типа mFlag, компилятора, уровня оптимизации
То есть какие-то операции могут быть или не быть атомарными в зависимости от кода? Не могу утверждать 100%, но очень вряд ли. Требуется 2 или более машинных команд (надо нести mFlag в регистр) значит не атомарно.

Если нет модификации mFlag в другом месте, то пожалуй соглашусь в контексте данного примера )
Ну если выполнение хотя бы 2 нитками - то др место уже есть  :)


Название: Re: Нужна ли блокировка ?
Отправлено: mutineer от Январь 24, 2012, 18:15
Если нет модификации mFlag в другом месте, то пожалуй соглашусь в контексте данного примера )
Ну если выполнение хотя бы 2 нитками - то др место уже есть  :)

Имеется в виду другое место в коде. Если две и более ниток одновременно выполняют data->mFlag |= 1;, то из-за сути операции | результат будет всегда один и тот же


Название: Re: Нужна ли блокировка ?
Отправлено: pastor от Январь 24, 2012, 19:44
Зависит от типа mFlag, компилятора, уровня оптимизации
То есть какие-то операции могут быть или не быть атомарными в зависимости от кода? Не могу утверждать 100%, но очень вряд ли. Требуется 2 или более машинных команд (надо нести mFlag в регистр) значит не атомарно.

Можно, напрмиер, заглянуть вот в эту статью (http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=469). В ней расматривается несколько операторов. Какой компилятор и какие параметры оптимизации использовались неуказано.


Название: Re: Нужна ли блокировка ?
Отправлено: pastor от Январь 24, 2012, 19:51
Но снова повторюсь, что полагаться на компилятор не стоит, темболее если речь идет о кросс-платформенной разработке


Название: Re: Нужна ли блокировка ?
Отправлено: Igors от Январь 24, 2012, 20:33
Можно, напрмиер, заглянуть вот в эту статью (http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=469).
Убедили, да, напр операция ++ может быть атомарной или нет в зависимости от кода (в общем случае нет). Но разговор не о том. Допустим сделали атомарно (неважно как реализован AtomicOr).
Код
C++ (Qt)
if ((data->mFlag & 1) == 0)
if (Test(data))
 AtomicOr(&data->mFlag, 1);  // или мутекс
 
Ну и что мы таким образом защитили? Я так вижу что аж ничего :) Взять весь кусок под мутекс - это работает всегда, но скорость может быть убита в ноль. Думается что (если ситуация позволяет) лучше смириться с тем что Test сработает впустую (когда уже mFlag стоит) чем связываться с локом