Название: if (a == localA) Отправлено: Igors от Февраль 14, 2016, 10:06 Код Этот участок кода НЕ защищен блокировками и может одновременно выполняться 2 или более нитками. Любая из них может менять переменную "a", переменная localA на стеке. Можем ли мы опираться на рез-т такого сравнения? Название: Re: if (a == localA) Отправлено: Old от Февраль 14, 2016, 10:19 Без указания типа A вопрос бессмысленный, я оператор == могу определить как угодно.
И что значит опираться на результаты? Название: Re: if (a == localA) Отправлено: Igors от Февраль 14, 2016, 10:34 Без указания типа A вопрос бессмысленный, я оператор == могу определить как угодно. Если, по Вашему мнению, зависит от типа и/или оператора, то ответ "Иногда" - с примерчиками когда да, а когда нет И что значит опираться на результаты? Значит в плече if'а мы уверены что равенство остается истиннымНазвание: Re: if (a == localA) Отправлено: Old от Февраль 14, 2016, 10:38 Значит в плече if'а мы уверены что равенство остается истинным Конечно нет. В некоторых случаях мы можем быть уверены, что в момент проверки равенство истино.Поэтому и усомнился в смысле опроса. Название: Re: if (a == localA) Отправлено: Akon от Февраль 14, 2016, 10:56 (a == localA) корректна, если:
1. Соответствующая ассемблерная инструкция будет атомарной (одной, а не состоять из нескольких). Если операнды не превышают используемого машинного слова, то инструкция будет атомарной. Например, для 32бит. кода все что меньше int (32 bit) дает одну инструкцию, а вот для int64 будет две инструкции. Я имею ввиду код для регистров общего назначения, SIMD-операнды (например, 256-битные) и в 32-х битном коде тоже будут атомарны. 2. a должна быть volatile. Название: Re: if (a == localA) Отправлено: Igors от Февраль 14, 2016, 11:07 (a == localA) корректна, если: Разумеется. Но вопрос был Можем ли мы опираться на рез-т такого сравнения? Т.е. речь идет о коде выполняемом в скобках if'a, который может быть достаточно (или сколь угодно) длинным Название: Re: if (a == localA) Отправлено: Bepec от Февраль 14, 2016, 12:17 неизвестны типы, неизвестны внешние условия, неизвестно может ли быть произведено удаление/замещение переменной. А так, если абстрагироваться от этих вещей, то уже ответили - при атомарной операции можем.
Название: Re: if (a == localA) Отправлено: Igors от Февраль 14, 2016, 12:40 неизвестны типы, неизвестны внешние условия, неизвестно может ли быть произведено удаление/замещение переменной. А так, если абстрагироваться от этих вещей, то уже ответили - при атомарной операции можем. Что такое "удаление/замещение" переменной - хз :) О том что все нитки могут ее писать/читать сказано ясно. Опасаетесь какой-то ловушки с типом - хорошо, пусть тип 'а' просто intНазвание: Re: if (a == localA) Отправлено: Akon от Февраль 14, 2016, 12:56 Цитировать Т.е. речь идет о коде выполняемом в скобках if'a, который может быть достаточно (или сколь угодно) длинным ?? абстрактный вопрос. А в чем принципиальная разница изменяется ли конкретной ниткой 'a' в 'if' блоке или где-то еще?В общем случае нужна синхронизация. Грамотно она делается так (блокировка с двойной проверкой): Код: if (a == localA) { Название: Re: if (a == localA) Отправлено: Igors от Февраль 14, 2016, 13:18 ?? абстрактный вопрос. А в чем принципиальная разница изменяется ли конкретной ниткой 'a' в 'if' блоке или где-то еще? Не спрашивается где и как меняется "a", с блокировками или без. Речь идет об участке коде которому необходимо чтобы равенство оставалось истинным, иначе он развалится// что-то делаем предполагая == В общем случае нужна синхронизация. Грамотно она делается так (блокировка с двойной проверкой): В условии сказаноЭтот участок кода НЕ защищен блокировками Да, неск лет назад Вы уже отвечали на почти такой же вопрос :) Название: Re: if (a == localA) Отправлено: Bepec от Февраль 14, 2016, 13:37 удаление/замещение - это удаление переменной или изменение указателя, т.к. тип у вас хз какой.
Название: Re: if (a == localA) Отправлено: Igors от Февраль 14, 2016, 15:21 Хоть один ответил "нет" - вот это по-мужски, а то когда же возможно то самое "иногда" когда кусок кода работает просто по if'у, и ничего не боится ?
удаление/замещение - это удаление переменной или изменение указателя, т.к. тип у вас хз какой. А Вы бы не калякали, а слушали что умные люди говорятКод Без захвата мутекса это не будет работать верно в 2 нитках, т.к. вызов QModelIndex::isValid() никак не атомарный. Хоть это уясните Название: Re: if (a == localA) Отправлено: Old от Февраль 14, 2016, 15:25 Хоть один ответил "нет" Ну так я вам в третьем посте это написал словами, а сейчас пришлось сделать выбор в опросе, что бы посмотреть результаты. :)Другого результата я и не ожидал. Название: Re: if (a == localA) Отправлено: Old от Февраль 14, 2016, 15:30 Хоть один ответил "нет" Но могу сделать "да", что-бы код выше стал корректным (с некоторыми условиями). :)Название: Re: if (a == localA) Отправлено: Bepec от Февраль 14, 2016, 17:19 Как печально Igors что вы не понимаете цимуса. Вы не подумали как index превратится в massiveRow[].
Наверно из него получим строку и столбец и после проверим есть ли такой элемент в массиве... Печально, не правда ли? И да, эти простейшие операции защищены мутексом в ф-ции data. Как же вы узко на мир глядите :) Название: Re: if (a == localA) Отправлено: Авварон от Февраль 14, 2016, 19:13 Как печально Igors что вы не понимаете цимуса. Вы не подумали как index превратится в massiveRow[]. Наверно из него получим строку и столбец и после проверим есть ли такой элемент в массиве... Печально, не правда ли? И да, эти простейшие операции защищены мутексом в ф-ции data. Как же вы узко на мир глядите :) Код: Thread B: Название: Re: if (a == localA) Отправлено: Bepec от Февраль 14, 2016, 19:56 Ммм.. вы невнимательно читали. Защитить ВСЕ функции РАБОТАЮЩИЕ с КОНТЕЙНЕРОМ. Я их даже перечислил. rowCount, Data,RemoveRows,InsertRows.
В вашем случае нитка A встанет на мутексе rowCount, дождётся удаления и пойдёт дальше. Разве нет? PS тут возможна иная ситуация - если будет повторный лок объекта внутри этих функций. Но мы же умные программисты и понимаем, что нужно опасаться выстрелов в ногу. Мы эти функции пишем, мы же за них и отвечаем. PPS специально ради вас создал программку по вашему псевдокоду. 40 потоков выполняют код нитки Б, вылетов не замечено, конфликтов не замечено, передаваемый размер и фактический размер не разнятся. Название: Re: if (a == localA) Отправлено: Авварон от Февраль 14, 2016, 20:48 Ммм.. вы невнимательно читали. Защитить ВСЕ функции РАБОТАЮЩИЕ с КОНТЕЙНЕРОМ. Я их даже перечислил. rowCount, Data,RemoveRows,InsertRows. В вашем случае нитка A встанет на мутексе rowCount, дождётся удаления и пойдёт дальше. Разве нет? Встанет, но данные _уже_ будут изменены, так как событие было положено в очередь под мьютексом, потом этот мьютекс разблокировали, а потом событие получила вьюха и полезла в модель. Если делать beginRemove через QueuedConnection, то мб будет работать. А вот changePersistentIndexes может поломаться. Ну то есть, еще раз: Код: Thread B: Название: Re: if (a == localA) Отправлено: Bepec от Февраль 14, 2016, 21:46 Весь прикол, что thread A не видит removeRows, т.к. он не имеет к нему доступа, не имеет к нему указателя и не может никак на него воздействовать. RemoveRows значимо только для модели.
Пока не будет вызвано endRemoveRows никаких действий View совершено не будет. В том и красота системы model-View. View, даже запрашивая самые невообразимые и чудовищные индексы, не вызывает никакой работы с данными, получая отлуп от модели. Попробуйте ради прикола позапрашивать неадекватные данные из модели - у вас в результате выйдет обычный пшик. Сам шаблон блокирует такую ситуацию, что View может напортачить что то с данными. Вся работа с данными лежит только в модели. View лишь отображает, причём ему прощается абсолютно всё, начиная от запроса и до удаления неверных индексов. PS верное отображение событий для Model/View Код: Model: Название: Re: if (a == localA) Отправлено: Igors от Февраль 15, 2016, 05:26 PPS специально ради вас создал программку по вашему псевдокоду. 40 потоков выполняют код нитки Б, вылетов не замечено, конфликтов не замечено, передаваемый размер и фактический размер не разнятся. Так выкладывайте проект (вместо того чтобы воздух гонять)Но могу сделать "да", что-бы код выше стал корректным (с некоторыми условиями). :) Пожалуйста - можете вводить любые условия/правила, но участок кода первого поста должен работать без блокировок. Название: Re: if (a == localA) Отправлено: Igors от Февраль 15, 2016, 05:32 Если делать beginRemove через QueuedConnection, то мб будет работать. Нет никакой необходимости лезть в такие тонкости. Развалится paint, sizeHint и все-все что держит QModelIndex. Залатать все блокировками нереально - быстро приходит понимание что сам подход "дырявый". Ну а по поводу "проверок" в неблокируемом коде - этому и посвящен данный топик :) А вот changePersistentIndexes может поломаться. Название: Re: if (a == localA) Отправлено: Old от Февраль 15, 2016, 07:56 Пожалуйста - можете вводить любые условия/правила, но участок кода первого поста должен работать без блокировок. Что вы имеете ввиду, говоря "работать без блокировок"? Без применение средст синхронизации?Название: Re: if (a == localA) Отправлено: Igors от Февраль 15, 2016, 08:25 Что вы имеете ввиду, говоря "работать без блокировок"? Без применение средст синхронизации? Что имею то и введу :) "Участок кода" - это код начинающийся с if и заканчивающийся закрывающейся скобкой. т.е. все содержимое тега code первого поста. "Неблокируемый" - значит для его выполнения не нужны никакие мутексы и др средства синхронизации. Но в любых других местах (напр для установки "a") можно использовать все что угодно.Название: Re: if (a == localA) Отправлено: Old от Февраль 15, 2016, 09:01 Что имею то и введу :) Лет 35 назад, по моему в первом классе, я слышал этот анекдот. Правда он меня не так сильно зацепил, как вас."Участок кода" - это код начинающийся с if и заканчивающийся закрывающейся скобкой. т.е. все содержимое тега code первого поста. "Неблокируемый" - значит для его выполнения не нужны никакие мутексы и др средства синхронизации. Но в любых других местах (напр для установки "a") можно использовать все что угодно. Легко:Код
Пожалуйста. Название: Re: if (a == localA) Отправлено: Igors от Февраль 15, 2016, 09:17 Легко: Наверное в первом классе Вы были тихим мальчиком, никого не трогали :)Код
Пожалуйста. Название: Re: if (a == localA) Отправлено: Old от Февраль 15, 2016, 09:49 Наверное в первом классе Вы были тихим мальчиком, никого не трогали :) Нет, умным.Со своим желанием по пинать Вереса, вы традиционно забыли правильно сформулировать свои мысли. О чем я вам уже вторую страницу пытаюсь донести. Но... :) Название: Re: if (a == localA) Отправлено: Igors от Февраль 15, 2016, 10:16 ..вы традиционно забыли правильно сформулировать свои мысли. Ну зачем, мягко говоря, "говорить неправду", причем систематически? Ведь это легко проверить, в первом посте ясно сказано, причем дважды// что-то делаем предполагая == Хорошо, "еще раз"... Можем ли мы опираться на рез-т такого сравнения? Код Хотя я прекрасно понимаю что это бесполезно, если уж человек включил "непонималку"... Название: Re: if (a == localA) Отправлено: Old от Февраль 15, 2016, 10:30 Хотя я прекрасно понимаю что это бесполезно, если уж человек включил "непонималку"... Как раз не правда это. Я вам дал ответ в третьем посте этой темы. :)А то, что вы не умеете формулировать свои мысли говорят ответы этой темы, например, ответ Akon. Вы задали вопрос про сравнение, а ответ ждали про корректность кода в блоке после проверки. Я это понял, и начал задавать вам наводящие вопросы, а Akon не понял и начал отвечать про сравнение. Уверен не поняли и почти все остальные, кроме трех (меня, Авварон, Пантер) ответивших нет . :) Название: Re: if (a == localA) Отправлено: Igors от Февраль 15, 2016, 13:46 Хорошо, подведем промежуточные итоги
Позиция 1: при параллельном выполнении само сравнение должно быть атомарным (см исчерпывающие пояснения Akon), иначе сразу до свидания. Правду сказать, я об этом даже не подумал когда создавал тему :) Позиция 2: но, как мы знаем, при параллельном выполнении возвращаемое значение означает лишь что "факт равенства имел место", т.е. это точно "было", но сейчас (когда выполняется следующая за if'oм) строка - это может быть уже не так. Ведь др нитка может успеть изменить значение "a", и с приветом Все же мой ответ был "Иногда да". Конечно нитки должны менять "a" по определенным правилам (на то оно и "иногда"). Есть желающие построить такую конструкцию? Еще раз напомню - вне кода первого поста Вы можете использовать любые средства синхронизации. Название: Re: if (a == localA) Отправлено: Bepec от Февраль 15, 2016, 17:23 Когда же до него дойдёт, что средства синхронизации специально созданы чтобы разруливать эту ситуацию.
И что любое решение данной проблемы сразу же будет занесено в список "средств синхронизации". Название: Re: if (a == localA) Отправлено: Old от Февраль 15, 2016, 18:32 Хорошо, подведем промежуточные итоги Вы не правильно представляете итоги. Нет никаких позиций 1 и 2, это все одна и таже позиция.Вы мыслите в каких-то строках программы, а на самом деле условие может измениться в той же самой строке. Т.е. и проверка и дальнейшее выполнение блока должно быть защищего какими-то средствами синхронизации. Все же мой ответ был "Иногда да". Конечно нитки должны менять "a" по определенным правилам (на то оно и "иногда"). Как правильно написал Верес: не-не-не! никаких правил. Каждое правило это блокировка, в вашей терминологии.Название: Re: if (a == localA) Отправлено: Igors от Февраль 16, 2016, 08:47 Рассмотрим похожий пример: "многопоточный" поиск максимума
Код Если текущий найденный максимум уже больше - то нечего и блокировки брать. Здесь внимание обычно сосредоточено на второй части, там примитивная ловушка Код При этом упускается из виду что if срабатывает всегда верно без блокировок, ну как бы "по алгоритму" или "по построению". Как то же самое сделать для == (вместо >)? Название: Re: if (a == localA) Отправлено: Igors от Февраль 18, 2016, 08:49 Как-то тихо стало :) Возможно подумали типа "ну там в каком-то конкретном алгоритме может и можно, но это сугубо частный случай". По аналогии с "поиском максимума". Все с точностью наоборот: сравнения >< только для арифметики и применимы, а вот равенство - случай весьма общий, от алгоритма практически не зависит. Даже Qt его использует :)
Название: Re: if (a == localA) Отправлено: Racheengel от Февраль 18, 2016, 10:17 Нет никакой гарантии, что компилятор будет настолько умным, что распознает поддержку многопоточности и сделает сравнение объектов атомарным. Поэтому лучше мутекс.
Название: Re: if (a == localA) Отправлено: Igors от Февраль 19, 2016, 07:11 Нет никакой гарантии, что компилятор будет настолько умным, что распознает поддержку многопоточности и сделает сравнение объектов атомарным. Поэтому лучше мутекс. Мда, в этом недостаток длинных тем - их никто не читает :) Если сравнение не атомарно - значит некорректно. Но это совсем не означает обратного - атомарность сравнения еще ничего не гарантирует. Вообще у пользователей Qt как-то неважно с логикой :) Название: Re: if (a == localA) Отправлено: Old от Февраль 19, 2016, 08:10 Мда, в этом недостаток длинных тем - их никто не читает :) Где вы видите длиную тему? Кое как наковыряли третью страницу.В этом недостаток "непонятных" тем. Это да. Если сравнение не атомарно - значит некорректно. Но это совсем не означает обратного - атомарность сравнения еще ничего не гарантирует. О, капитан очевидность в теме. :)Вообще у пользователей Qt как-то неважно с логикой :) Точно. Эта темка в очередной раз это подтверждает, впрочем как и соседняя. :) |