ksd>возможен ли готовый хороший субж в природе? ksd>(вектор, лист, сет или их аналоги -- все подойдет)
А что такое неинвалидирующие итераторы?
А то в С++17 контейнеры уже сделаны потокобезопасными вроде.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: нужен контейнер, потокобезопасный, с неинвалидирующимися ите
Здравствуйте, LaptevVV, Вы писали:
ksd>>возможен ли готовый хороший субж в природе? ksd>>(вектор, лист, сет или их аналоги -- все подойдет) LVV>А что такое неинвалидирующие итераторы? LVV>А то в С++17 контейнеры уже сделаны потокобезопасными вроде.
Re[2]: нужен контейнер, потокобезопасный, с неинвалидирующимися ите
Здравствуйте, LaptevVV, Вы писали:
ksd>>возможен ли готовый хороший субж в природе? ksd>>(вектор, лист, сет или их аналоги -- все подойдет) LVV>А что такое неинвалидирующие итераторы?
в треде 1 получаем итератор и перебираем элементы в контейнере, в треде 2 делаем insert или erase -- итератор в треде 1 не отваливается.
LVV>А то в С++17 контейнеры уже сделаны потокобезопасными вроде.
это замечательно!
Re[3]: нужен контейнер, потокобезопасный, с неинвалидирующимися ите
Здравствуйте, ksd, Вы писали:
ksd>в треде 1 получаем итератор и перебираем элементы в контейнере, в треде 2 делаем insert или erase -- итератор в треде 1 не отваливается.
А теперь следующий вопрос: что должно произойти про инкременте/декременте этого итератора? От этого и плясать.
Re[4]: нужен контейнер, потокобезопасный, с неинвалидирующимися ите
Здравствуйте, IID, Вы писали:
IID>Здравствуйте, ksd, Вы писали:
LVV>>>А то в С++17 контейнеры уже сделаны потокобезопасными вроде. ksd>>это замечательно!
IID>Внутренняя потокобезопасность это тормоза.
может у него в контейнере 100 элементов и обращения к нему пару раз в минуту
если это не так ТС написал об этом в первом сообщение
Re[2]: нужен контейнер, потокобезопасный, с неинвалидирующимися ите
Здравствуйте, sergey2b, Вы писали:
S>Здравствуйте, IID, Вы писали:
IID>>Здравствуйте, ksd, Вы писали:
LVV>>>>А то в С++17 контейнеры уже сделаны потокобезопасными вроде. ksd>>>это замечательно!
IID>>Внутренняя потокобезопасность это тормоза.
S>может у него в контейнере 100 элементов и обращения к нему пару раз в минуту S>если это не так ТС написал об этом в первом сообщение
++ "у него" в контейнере ~10 элементов, но много обращений на чтение:
и с очень маленькой вероятностью в миллионы раз реже может быть из другого треда subscribers.insert(some) или erase;
завернуть for в критическую секцию не вариант.
Re: нужен контейнер, потокобезопасный, с неинвалидирующимися
Здравствуйте, ksd, Вы писали:
ksd>возможен ли готовый хороший субж в природе?
Нет. Но если возник такой вопрос, то самый правильный ответ — нужно продумывать архитектуру.
ksd>(вектор, лист, сет или их аналоги -- все подойдет)
Сферической потокобезопасности в вакууме не бывает. Ее можно натянуть на контейнеры, которые используются исключительно через операции единичной вставки/чтения (очередь, к примеру)
Попытка сделать "потокобезопасными" контейнеры, по которым необходимо итерироваться, в конечном итоге приводит к куче проблем и выкорчевыванию "изобретения" из проекта.
for (auto i = container.begin(); i != container.end(); ++i)
{
auto some_value = do_something_with(*i);
call_some_other_code(some_value);
// another 100500 lines of code
}
Код выше нельзя в общем случае сделать потокобезопасным средствами контейнера.
Здравствуйте, landerhigh, Вы писали:
L>Здравствуйте, ksd, Вы писали:
ksd>>возможен ли готовый хороший субж в природе?
L>Нет. Но если возник такой вопрос, то самый правильный ответ — нужно продумывать архитектуру.
ksd>>(вектор, лист, сет или их аналоги -- все подойдет)
L>Сферической потокобезопасности в вакууме не бывает. Ее можно натянуть на контейнеры, которые используются исключительно через операции единичной вставки/чтения (очередь, к примеру)
L>Попытка сделать "потокобезопасными" контейнеры, по которым необходимо итерироваться, в конечном итоге приводит к куче проблем и выкорчевыванию "изобретения" из проекта.
L>
L>for (auto i = container.begin(); i != container.end(); ++i)
L>{
L> auto some_value = do_something_with(*i);
L> call_some_other_code(some_value);
L> // another 100500 lines of code
L>}
L>
L>Код выше нельзя в общем случае сделать потокобезопасным средствами контейнера.
это еще почему?! итератор может же в операторе ++ поинтересоваться, обновился контейнер или нет?
Re[3]: нужен контейнер, потокобезопасный, с неинвалидирующимися
Здравствуйте, ksd, Вы писали:
L>>Код выше нельзя в общем случае сделать потокобезопасным средствами контейнера. ksd>это еще почему?! итератор может же в операторе ++ поинтересоваться, обновился контейнер или нет?
Может. Ну, допустим, обновился (если раньше не упадет, см. ниже). Дальше что?
Далее:
some_type do_something_with(const some_other_type& what)
{
//....
}
for (auto i = container.begin(); i != container.end(); ++i)
{
auto some_value = do_something_with(*i); // А в этот прекрасный момент другой поток делает контейнеру clear()
}
Иными словами, попытка изобрести универсальный потокобезопасный контейнер ни к чему хорошему не приводит.
Здравствуйте, ksd, Вы писали:
ksd>это еще почему?! итератор может же в операторе ++ поинтересоваться, обновился контейнер или нет?
Ну, поинтересовался он. Услышал в ответ "вас тут не стояло", потому что контейнер с тех пор успели дважды очистить и заново наполнить. Что тогда делаем в плюс-плюсинге?
Re[4]: нужен контейнер, потокобезопасный, с неинвалидирующимися
Здравствуйте, Mr.Delphist, Вы писали:
ksd>>это еще почему?! итератор может же в операторе ++ поинтересоваться, обновился контейнер или нет? MD>Ну, поинтересовался он. Услышал в ответ "вас тут не стояло", потому что контейнер с тех пор успели дважды очистить и заново наполнить. Что тогда делаем в плюс-плюсинге?
В его случае самым оптимальным было бы снапшотиться, т.е. старый итератор должен будет продолжать обход старой коллекции. С случае наличия gc (в java) я бы делал так:
volatile Set<Subsc_t> subscribers = Collections.emptySet();
public void doSome()
{//тут локи не нужны, т.к. коллекция никогда не меняетсяfor (var s: subscribers) {
s->doSome();
}
}
public void add(Subscrber s)
{
synchronized(lock) {
var newSubscribers = new HashSet<>(subscribers);//потому что мы всегда создаём новую
newSubscribers.add(s);
subscribers = newSubscribers;
}
}
Без gc что-то даже не знаю как это нормально сделать... Идеи?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[2]: нужен контейнер, потокобезопасный, с неинвалидирующимися
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, landerhigh, Вы писали:
L>>
L>>for (auto i = container.begin(); i != container.end(); ++i)
L>>{
L>> auto some_value = do_something_with(*i);
L>> call_some_other_code(some_value);
L>> // another 100500 lines of code
L>>}
L>>
L>>Код выше нельзя в общем случае сделать потокобезопасным средствами контейнера.
BFE>Представьте, что ваш контейнер — это база данных. Не существует баз данных, с которыми можно работать из нескольких потоков?
И тем не менее правда на стороне .
А все попытки натянуть сову на глобус с неуместными аналогиями — это просто капризы дилетантов, незнакомых с элементарными, базисными вещами. Тем, как именно, в какую сторону продумывается архитектура и взаимодействие со структурами данным в объектной модели малтитредового софта.
Из разряда: «да, мы пишем на С++, но давайте чтобы без эксепшенов, а то как-то сложно с ними получается».
Зачем цепляться за идиому итераторов в плане многопоточного доступа к контейнеру? Чтобы героически бороться с мельницами?
Что афтар топика решает своим итерированием по контейнеру? Делает последовательный проход, для чего? Чтобы последовательно вызвать несколько обработчиков/действий.
Не уж то это же самое нельзя сделать иначе как через последовательный доступ итератором?
Содержимое этого контенера — есть пачка заданий для треда, с вероятностью 1/(10³×10³) в процессе выполнения может потребоваться добавить или убрать что-то из этой пачки из другого треда. И что, это конец света? Иначе чем через итераторы не сделать?
Re[3]: нужен контейнер, потокобезопасный, с неинвалидирующимися
Здравствуйте, B0FEE664, Вы писали:
L>>Код выше нельзя в общем случае сделать потокобезопасным средствами контейнера. BFE>Представьте, что ваш контейнер — это база данных. Не существует баз данных, с которыми можно работать из нескольких потоков?
Речь идет о контейнерах.
Попытка сделать из контейнера базу данных с преферансом, барышнями и transaction isolation только потому, что авторам лень или не хватает терпения продумать архитектуру ведет к эпичному провалу более чем всегда.
Когда нужно именно хранилище с транзакционностью, со снапшотами и т.п., тогда и вопрос ставят именно так
Здравствуйте, ·, Вы писали:
MD>>Ну, поинтересовался он. Услышал в ответ "вас тут не стояло", потому что контейнер с тех пор успели дважды очистить и заново наполнить. Что тогда делаем в плюс-плюсинге? ·>В его случае самым оптимальным было бы снапшотиться,
продумывать архитектуру.
Дело в том, что от постановки вопроса веет подходом "мы не знаем, сколько у нас будет потоков и вообще не подумали о межпоточном взаимодействии, поэтому нам нужен потокобезопасный контейнер".
Классический "Failing to plan is planning to fail".
Здравствуйте, ksd, Вы писали:
ksd>++ "у него" в контейнере ~10 элементов, но много обращений на чтение: ksd>и с очень маленькой вероятностью в миллионы раз реже может быть из другого треда subscribers.insert(some) или erase; ksd>завернуть for в критическую секцию не вариант.