Здравствуйте, VVV, Вы писали:
VVV>·>Не выйдет. size() тоже вообще-то надо внутрь lock засовывать, что делает всю затею бессмысленной. VVV>·>Можно вместо size() использовать atomic int или что-то подобное, но тоже непригодно для low latency, т.к. doSome может ВНЕЗАПНО лочиться. VVV>size() имеется в виду функция типа size_t size() { return m_size; }
Т.е. завязываешься на конкретную реализацию конкретного контейнера...
VVV>, в данном случае lock вызывать не надо, нам совсем не важно правильная ли сумма вернётся, важно только что сумма больше 0. Поэтому тут lock не нужен. И да — это был псевдокод — можно вместо size() завести булевскую переменную.
... но всё равно без разницы. Чтение переменной из одного потока, когда она меняется из другого просто так, без всяких многопоточных штуковин — вещь как повезёт. Например, значение 0 может закешироваться в регистре одного потока и из памяти никогда не читаться и изменения в памяти другим потоком не будут видны. Как мининмум нужен membar.
Приведённый ранее код — ошибочен. Если ты так делаешь в реальном коде — обязательно исправь, это бага.
VVV>Про ВНЕЗАПНО лочиться — при многопоточном доступе к данным такое случается. В предложенном мной подходе lock будет вызываться только в случае реального добавления/удаления данных.
Это зависит от требований. В low latecny code такое не должно случаться. Поэтому там нужны специальные lock-free подходы.
VVV>Ещё алгоритм придумался: использовать кольцевой буфер новых/удаляемых объектов. insert/erase двигают tail, doSome двигает head.
Да, такое вроде сработает, но только если doSome выполняется из максимум одного потока.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай