Russian Qt Forum
Ноябрь 22, 2024, 21:28 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Голосование
Вопрос: Корректен ли этот код при параллельном исполнении без блокировок ?
Да - 0 (0%)
Нет - 4 (44.4%)
Иногда да - 3 (33.3%)
Ваш вариант - 2 (22.2%)
Всего голосов: 8

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: if (a == localA)  (Прочитано 16879 раз)
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #15 : Февраль 14, 2016, 19:13 »

Как печально Igors что вы не понимаете цимуса. Вы не подумали как index превратится в massiveRow[].
Наверно из него получим строку и столбец и после проверим есть ли такой элемент в массиве... Печально, не правда ли? И да, эти простейшие операции защищены мутексом в ф-ции data. Как же вы узко на мир глядите Улыбающийся

Код:
Thread B:
lock();
beginRemoveRows() -> signal
removeRows();
endRemoveRows() -> signal
unlock();

ThreadA
onBeginRemoveRows()
{
    int rowCount = model->rowCount(); /// упс, тут новый каунт, а вью ожидает старый, это же BEGIN removeRows, а они уже удалены.
}
Записан
Bepec
Гость
« Ответ #16 : Февраль 14, 2016, 19:56 »

Ммм.. вы невнимательно читали. Защитить ВСЕ функции РАБОТАЮЩИЕ с КОНТЕЙНЕРОМ. Я их даже перечислил. rowCount, Data,RemoveRows,InsertRows.

В вашем случае нитка A встанет на мутексе rowCount, дождётся удаления и пойдёт дальше. Разве нет?

PS тут возможна иная ситуация - если будет повторный лок объекта внутри этих функций. Но мы же умные программисты и понимаем, что нужно опасаться выстрелов в ногу. Мы эти функции пишем, мы же за них и отвечаем.

PPS специально ради вас создал программку по вашему псевдокоду. 40 потоков выполняют код нитки Б, вылетов не замечено, конфликтов не замечено, передаваемый размер и фактический размер не разнятся.
« Последнее редактирование: Февраль 14, 2016, 20:07 от Bepec » Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #17 : Февраль 14, 2016, 20:48 »

Ммм.. вы невнимательно читали. Защитить ВСЕ функции РАБОТАЮЩИЕ с КОНТЕЙНЕРОМ. Я их даже перечислил. rowCount, Data,RemoveRows,InsertRows.

В вашем случае нитка A встанет на мутексе rowCount, дождётся удаления и пойдёт дальше. Разве нет?

Встанет, но данные _уже_ будут изменены, так как событие было положено в очередь под мьютексом, потом этот мьютекс разблокировали, а потом событие получила вьюха и полезла в модель.
Если делать beginRemove через QueuedConnection, то мб будет работать.
А вот changePersistentIndexes может поломаться.

Ну то есть, еще раз:
Код:
Thread B:
beginRemoveRows() -> signal
removeRows();
endRemoveRows() -> signal

Как это видит Thread А:
removeRows();
beginRemoveRows()
endRemoveRows()
Записан
Bepec
Гость
« Ответ #18 : Февраль 14, 2016, 21:46 »

Весь прикол, что thread A не видит removeRows, т.к. он не имеет к нему доступа, не имеет к нему указателя и не может никак на него воздействовать. RemoveRows значимо только для модели.

Пока не будет вызвано endRemoveRows никаких действий View совершено не будет.
В том и красота системы model-View. View, даже запрашивая самые невообразимые и чудовищные индексы, не вызывает никакой работы с данными, получая отлуп от модели.

Попробуйте ради прикола позапрашивать неадекватные данные из модели - у вас в результате выйдет обычный пшик. Сам шаблон блокирует такую ситуацию, что View может напортачить что то с данными. Вся работа с данными лежит только в модели. View лишь отображает, причём ему прощается абсолютно всё, начиная от запроса и до удаления неверных индексов.

PS верное отображение событий для Model/View
Код:
Model:
beginRemoveRows() -> signal
removeRows();
endRemoveRows() -> signal

Как это видит View:
beginRemoveRows()
endRemoveRows()
update()
« Последнее редактирование: Февраль 14, 2016, 21:48 от Bepec » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #19 : Февраль 15, 2016, 05:26 »

PPS специально ради вас создал программку по вашему псевдокоду. 40 потоков выполняют код нитки Б, вылетов не замечено, конфликтов не замечено, передаваемый размер и фактический размер не разнятся.
Так выкладывайте проект (вместо того чтобы воздух гонять)

Но могу сделать "да", что-бы код выше стал корректным (с некоторыми условиями). Улыбающийся
Пожалуйста - можете вводить любые условия/правила, но участок кода первого поста должен работать без блокировок. 
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #20 : Февраль 15, 2016, 05:32 »

Если делать beginRemove через QueuedConnection, то мб будет работать.
А вот changePersistentIndexes может поломаться.
Нет никакой необходимости лезть в такие тонкости. Развалится paint, sizeHint и все-все что держит QModelIndex. Залатать все блокировками нереально - быстро приходит понимание что сам подход "дырявый". Ну а по поводу "проверок" в неблокируемом коде - этому и посвящен данный топик  Улыбающийся 
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #21 : Февраль 15, 2016, 07:56 »

Пожалуйста - можете вводить любые условия/правила, но участок кода первого поста должен работать без блокировок. 
Что вы имеете ввиду, говоря "работать без блокировок"? Без применение средст синхронизации?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #22 : Февраль 15, 2016, 08:25 »

Что вы имеете ввиду, говоря "работать без блокировок"? Без применение средст синхронизации?
Что имею то и введу Улыбающийся "Участок кода" - это код начинающийся с if и заканчивающийся закрывающейся скобкой. т.е. все содержимое тега code первого поста. "Неблокируемый" - значит для его выполнения не нужны никакие мутексы и др средства синхронизации. Но в любых других местах (напр для установки "a") можно использовать все что угодно.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #23 : Февраль 15, 2016, 09:01 »

Что имею то и введу Улыбающийся
Лет 35 назад, по моему в первом классе, я слышал этот анекдот. Правда он меня не так сильно зацепил, как вас.

"Участок кода" - это код начинающийся с if и заканчивающийся закрывающейся скобкой. т.е. все содержимое тега code первого поста. "Неблокируемый" - значит для его выполнения не нужны никакие мутексы и др средства синхронизации. Но в любых других местах (напр для установки "a") можно использовать все что угодно.
Легко:
Код
C++ (Qt)
if( a == localA )
{
   int b;
   b++;
}
 

Пожалуйста.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #24 : Февраль 15, 2016, 09:17 »

Легко:
Код
C++ (Qt)
if( a == localA )
{
   int b;
   b++;
}
 

Пожалуйста.
Наверное в первом классе Вы были тихим мальчиком, никого не трогали  Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #25 : Февраль 15, 2016, 09:49 »

Наверное в первом классе Вы были тихим мальчиком, никого не трогали  Улыбающийся
Нет, умным.

Со своим желанием по пинать Вереса, вы традиционно забыли правильно сформулировать свои мысли. О чем я вам уже вторую страницу пытаюсь донести. Но... Улыбающийся
« Последнее редактирование: Февраль 15, 2016, 09:53 от Old » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #26 : Февраль 15, 2016, 10:16 »

..вы традиционно забыли правильно сформулировать свои мысли.
Ну зачем, мягко говоря, "говорить неправду", причем систематически? Ведь это легко проверить, в первом посте ясно сказано, причем дважды
// что-то делаем предполагая  ==
...
Можем ли мы опираться на рез-т такого сравнения?
Хорошо, "еще раз"
Код
C++ (Qt)
if (a == localA) {
data.push_back(0); // мы уверены что доступ к контейнеру data сейчас безопасен
...
}
Хотя я прекрасно понимаю что это бесполезно, если уж человек включил "непонималку"...
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #27 : Февраль 15, 2016, 10:30 »

Хотя я прекрасно понимаю что это бесполезно, если уж человек включил "непонималку"...
Как раз не правда это. Я вам дал ответ в третьем посте этой темы. Улыбающийся

А то, что вы не умеете формулировать свои мысли говорят ответы этой темы, например, ответ Akon.
Вы задали вопрос про сравнение, а ответ ждали про корректность кода в блоке после проверки.
Я это понял,  и начал задавать вам наводящие вопросы, а Akon не понял и начал отвечать про сравнение. Уверен не поняли и почти все остальные, кроме трех (меня, Авварон, Пантер) ответивших нет . Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #28 : Февраль 15, 2016, 13:46 »

Хорошо, подведем промежуточные итоги

Позиция 1: при параллельном выполнении само сравнение должно быть атомарным (см исчерпывающие пояснения Akon), иначе сразу до свидания. Правду сказать, я об этом даже не подумал когда создавал тему  Улыбающийся

Позиция 2: но, как мы знаем, при параллельном выполнении возвращаемое значение означает лишь что "факт равенства имел место", т.е. это точно "было", но сейчас (когда выполняется следующая за if'oм) строка - это может быть уже не так. Ведь др нитка может успеть изменить значение "a", и с приветом

Все же мой ответ был "Иногда да". Конечно нитки должны менять "a" по определенным правилам (на то оно и "иногда"). Есть желающие построить такую конструкцию? Еще раз напомню - вне кода первого поста Вы можете использовать любые средства синхронизации. 
Записан
Bepec
Гость
« Ответ #29 : Февраль 15, 2016, 17:23 »

Когда же до него дойдёт, что средства синхронизации специально созданы чтобы разруливать эту ситуацию.
И что любое решение данной проблемы сразу же будет занесено в список "средств синхронизации".
Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.471 секунд. Запросов: 25.