Re[3]: нужен контейнер, потокобезопасный, с неинвалидирующимися
От: Ops Россия  
Дата: 09.08.18 10:52
Оценка: +1
Здравствуйте, B0FEE664, Вы писали:

BFE>Представьте, что ваш контейнер — это база данных. Не существует баз данных, с которыми можно работать из нескольких потоков?


Контейнер — это не база данных. Если нужна база данных, КО советует взять базу данных.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[3]: нужен контейнер, потокобезопасный, с неинвалидирующимися ите
От: LaptevVV Россия  
Дата: 09.08.18 11:40
Оценка:
LVV>>А то в С++17 контейнеры уже сделаны потокобезопасными вроде.
U>о чем речь? что изменилось в плане потокобезопасности для старых контейнеров или какие-то новые контейнеры появились?
Да фигню спорол.
Параллельныее версии алгоритмов появились, которые нормально со стандартными контейнерами работают.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[4]: нужен контейнер, потокобезопасный, с неинвалидирующимися
От: B0FEE664  
Дата: 09.08.18 12:07
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Речь идет о контейнерах.

И?

L>Попытка сделать из контейнера базу данных с преферансом, барышнями и transaction isolation только потому, что авторам лень или не хватает терпения продумать архитектуру ведет к эпичному провалу более чем всегда.


Может приводит, а может и нет, только вот к "Код выше нельзя в общем случае сделать потокобезопасным средствами контейнера" это отношения не имеет.
И каждый день — без права на ошибку...
Re[7]: у него много обращений на чтение, и очень очень редко на запись
От: ksd Россия  
Дата: 09.08.18 12:11
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, ksd, Вы писали:


ksd>>++ "у него" в контейнере ~10 элементов, но много обращений на чтение:

ksd>>и с очень маленькой вероятностью в миллионы раз реже может быть из другого треда subscribers.insert(some) или erase;
ksd>>завернуть for в критическую секцию не вариант.

К>А завернуть в read-write lock — вариант?


К>В С++17 это называется std::shared_mutex.

возможно, это самое простое решение...
Re[4]: нужен контейнер, потокобезопасный, с неинвалидирующимися
От: B0FEE664  
Дата: 09.08.18 12:21
Оценка:
Здравствуйте, Ops, Вы писали:

BFE>>Представьте, что ваш контейнер — это база данных. Не существует баз данных, с которыми можно работать из нескольких потоков?

Ops>Контейнер — это не база данных. Если нужна база данных, КО советует взять базу данных.

Это вы просто не знакомы с безумными реалиями современного софтостроения. Например, деятели из Массачусетса сделали из базы данных real-time (sic!) систему обмена данными и на её основе пишут бортовой софт для боевых самолётов США.
И каждый день — без права на ошибку...
Re[5]: нужен контейнер, потокобезопасный, с неинвалидирующимися
От: landerhigh Пират  
Дата: 09.08.18 12:26
Оценка:
Здравствуйте, B0FEE664, Вы писали:

L>>Речь идет о контейнерах.

BFE>И?

Что "И"?

L>>Попытка сделать из контейнера базу данных с преферансом, барышнями и transaction isolation только потому, что авторам лень или не хватает терпения продумать архитектуру ведет к эпичному провалу более чем всегда.

BFE>Может приводит, а может и нет, только вот к "Код выше нельзя в общем случае сделать потокобезопасным средствами контейнера" это отношения не имеет.

В общем слуае — нельзя.
В частных случаях вроде очереди, а при определенных юзкейсах и другие контейнеры тоже можно. А в общем — нельзя.

База данных != контейнер.
www.blinnov.com
Re[6]: нужен контейнер, потокобезопасный, с неинвалидирующимися
От: ksd Россия  
Дата: 09.08.18 12:35
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Здравствуйте, ·, Вы писали:


MD>>>Ну, поинтересовался он. Услышал в ответ "вас тут не стояло", потому что контейнер с тех пор успели дважды очистить и заново наполнить. Что тогда делаем в плюс-плюсинге?

L>·>В его случае самым оптимальным было бы снапшотиться,

L>продумывать архитектуру.


++ хорошо. примеры или решения есть как то можно посмотреть / почитать о?
Re[6]: нужен контейнер, потокобезопасный, с неинвалидирующимися
От: B0FEE664  
Дата: 09.08.18 12:46
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>>>Речь идет о контейнерах.

BFE>>И?
L>Что "И"?
Чем таблица в базе данных не контейнер?

L>В общем слуае — нельзя.

L>В частных случаях вроде очереди, а при определенных юзкейсах и другие контейнеры тоже можно. А в общем — нельзя.
Погодите. Указан был вполне конкретный код с итераторами, а не абы какой.
И каждый день — без права на ошибку...
Re[5]: нужен контейнер, потокобезопасный, с неинвалидирующимися
От: Ops Россия  
Дата: 09.08.18 12:47
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Это вы просто не знакомы с безумными реалиями современного софтостроения. Например, деятели из Массачусетса сделали из базы данных real-time (sic!) систему обмена данными и на её основе пишут бортовой софт для боевых самолётов США.


Так базу данных или контейнер они взяли?
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[6]: нужен контейнер, потокобезопасный, с неинвалидирующимися
От: B0FEE664  
Дата: 09.08.18 13:03
Оценка:
Здравствуйте, Ops, Вы писали:

Ops>Так базу данных или контейнер они взяли?


Базу данных.
И каждый день — без права на ошибку...
Re[7]: нужен контейнер, потокобезопасный, с неинвалидирующимися
От: landerhigh Пират  
Дата: 09.08.18 13:11
Оценка:
Здравствуйте, ksd, Вы писали:

L>>продумывать архитектуру.

ksd>++ хорошо. примеры или решения есть как то можно посмотреть / почитать о?

Вряд ли смогу с наскоку порекомендовать литературу.

Все начинается с постановки задачи.
Сначала нужно понять, из чего появилось желание иметь потокобезопасный контейнер.
www.blinnov.com
Re[7]: троллинг детектед (-)
От: landerhigh Пират  
Дата: 09.08.18 13:12
Оценка:
www.blinnov.com
Re[8]: нужен контейнер, потокобезопасный, с неинвалидирующимися
От: ksd Россия  
Дата: 09.08.18 13:14
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Здравствуйте, ksd, Вы писали:


L>>>продумывать архитектуру.

ksd>>++ хорошо. примеры или решения есть как то можно посмотреть / почитать о?

L>Вряд ли смогу с наскоку порекомендовать литературу.


L>Все начинается с постановки задачи.

L>Сначала нужно понять, из чего появилось желание иметь потокобезопасный контейнер.
++ чтобы не переписывать имеющийся код. кривовато, конечно, но...
Re[7]: у него много обращений на чтение, и очень очень редко на запись
От: · Великобритания  
Дата: 09.08.18 13:34
Оценка:
Здравствуйте, Кодт, Вы писали:

ksd>>завернуть for в критическую секцию не вариант.

К>А завернуть в read-write lock — вариант?
К>В С++17 это называется std::shared_mutex.
Чем это принципиально будет отличаться от критической секции?
readers так же друг-друга могут блокировать во время write.
Впрочем, если ему не нужно low latency, то это не должно быть проблемой.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[4]: нужен контейнер, потокобезопасный, с неинвалидирующимися
От: · Великобритания  
Дата: 09.08.18 13:37
Оценка:
Здравствуйте, Ops, Вы писали:

BFE>>Представьте, что ваш контейнер — это база данных. Не существует баз данных, с которыми можно работать из нескольких потоков?

Ops>Контейнер — это не база данных. Если нужна база данных, КО советует взять базу данных.
Он написал "завернуть for в критическую секцию не вариант". А обычная база данных как раз это и сделает, правда очень неявно, через 100500 слоёв абстракции. Так что КО немного поспешил.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[5]: нужен контейнер, потокобезопасный, с неинвалидирующимися
От: Ops Россия  
Дата: 09.08.18 13:43
Оценка:
Здравствуйте, ·, Вы писали:

·>Он написал "завернуть for в критическую секцию не вариант". А обычная база данных как раз это и сделает, правда очень неявно, через 100500 слоёв абстракции. Так что КО немного поспешил.


КО отвечал B0FEE664, а не ТС.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[9]: нужен контейнер, потокобезопасный, с неинвалидирующимися
От: landerhigh Пират  
Дата: 09.08.18 13:54
Оценка:
Здравствуйте, ksd, Вы писали:

L>>Все начинается с постановки задачи.

L>>Сначала нужно понять, из чего появилось желание иметь потокобезопасный контейнер.
ksd>++ чтобы не переписывать имеющийся код. кривовато, конечно, но...

К сожалению, если имеющийся код представляет собой макароны, приправленные многопоточностью, то совсем без переписывания вряд ли выйдет.

Если дело в рефакторинге, то есть три пути. Либо отрефакторить код, из-за которого возникает такое желание. Либо потратить человекомесяцы на понимание его логики. Тогда, возможно, повезет и можно будет придумать контейнер, который сделает код потокобезопасным. Еще можно попробовать убрать многопоточность совсем.
www.blinnov.com
Re[6]: у него много обращений на чтение, и очень очень редко на запись
От: VVV Россия  
Дата: 09.08.18 15:10
Оценка:
Здравствуйте, ksd, Вы писали:

ksd>++ "у него" в контейнере ~10 элементов, но много обращений на чтение:

ksd>
ksd>    struct Subsc_t {
ksd>        virtual void doSome() = 0;
ksd>    };

ksd>    set<Subsc_t*> subscribers;

ksd>    for (auto s: subscribers) {
        s->>doSome();
ksd>    }
ksd>

ksd>и с очень маленькой вероятностью в миллионы раз реже может быть из другого треда subscribers.insert(some) или erase;
ksd>завернуть for в критическую секцию не вариант.

Сделать потокобезопасно в данном случае можно, если insert/erase делать в этом же потоке, где и обработка. Примерно так: завести ещё 2 контайнера insertedItems/erasedItems и критикал секшин на доступ к этим контейнерам.

псевдокод:
insert(some)
{
  cs.lock()
  insertedItems.insert(some)
  cs.unlock()
}
erase(some)
{
  cs.lock()
  erasedItems.insert(some)
  cs.unlock()
}

doSome()
{
  for(){...}
  if(insertedItems.size()+erasedItems.size() > 0)
  {
     cs.lock();
     //insert or erase to/from subscribers
     cs.unlock();
  }
}
Re[7]: у него много обращений на чтение, и очень очень редко
От: · Великобритания  
Дата: 09.08.18 15:27
Оценка:
Здравствуйте, VVV, Вы писали:

VVV>doSome()
VVV>{
VVV>  for(){...}
VVV>  if(insertedItems.size()+erasedItems.size() > 0)
VVV>  {
VVV>     cs.lock();
VVV>     //insert or erase to/from subscribers
VVV>     cs.unlock();
VVV>  }
VVV>}

Не выйдет. size() тоже вообще-то надо внутрь lock засовывать, что делает всю затею бессмысленной.
Можно вместо size() использовать atomic int или что-то подобное, но тоже непригодно для low latency, т.к. doSome может ВНЕЗАПНО лочиться.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Отредактировано 09.08.2018 15:28 · . Предыдущая версия .
Re[8]: у него много обращений на чтение, и очень очень редко
От: VVV Россия  
Дата: 09.08.18 16:13
Оценка:
Здравствуйте, ·, Вы писали:

·>Не выйдет. size() тоже вообще-то надо внутрь lock засовывать, что делает всю затею бессмысленной.

·>Можно вместо size() использовать atomic int или что-то подобное, но тоже непригодно для low latency, т.к. doSome может ВНЕЗАПНО лочиться.

size() имеется в виду функция типа size_t size() { return m_size; }, в данном случае lock вызывать не надо, нам совсем не важно правильная ли сумма вернётся, важно только что сумма больше 0. Поэтому тут lock не нужен. И да — это был псевдокод — можно вместо size() завести булевскую переменную.

Про ВНЕЗАПНО лочиться — при многопоточном доступе к данным такое случается. В предложенном мной подходе lock будет вызываться только в случае реального добавления/удаления данных.

Ещё алгоритм придумался: использовать кольцевой буфер новых/удаляемых объектов. insert/erase двигают tail, doSome двигает head.

doSome()
{
  for(){...}
  //for insert objects
  if(head != tail)
  {
    tail_=atomicget(tail);
    from(head to tail_){...}
    head=tail_;
  }
}

insert(some)
{
  insertedObjects[(tail+1)%bufsize]=some;
  atomicset(tail, (tail+1)%bufsize);
}


Если insert/erase случаются редко, как говорит ТС, то размер буфера можно подобрать исходя из здравого смысла.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.