Ищу библиотеку с контейнерами, в которых потокобезопасность получше чем в STL.
Посоветуйте кто какие знает, даже если потокобезопасность идет в ущерб функциональности и универсальности.
Уж больно свои делать неохота. Fifo-контейнер нашел, но его мало, а писать самому — боюсь закопаться
Здравствуйте, Garrett, Вы писали:
G>Ищу библиотеку с контейнерами, в которых потокобезопасность получше чем в STL.
G>Посоветуйте кто какие знает, даже если потокобезопасность идет в ущерб функциональности и универсальности. G>Уж больно свои делать неохота. Fifo-контейнер нашел, но его мало, а писать самому — боюсь закопаться
Не мучайся этой блажью
Синхронизируй доступ к контейнеру извне
Пример
пусть у тебя есть враппер над vector в котором во всех методах вставлена синхронизация например по критической секции
И что ты думаеш это тебя спасло и ничего делать больше не надо
Ошибаешся
Где гарантия что после строки 1 не выполнится код Thread2() и не удалит весь контейнер
Вывод всю покобезопасность надо реализовать извне а не внутри контейнеров
КР>Здравствуйте, Garrett, Вы писали:
G>>Ищу библиотеку с контейнерами, в которых потокобезопасность получше чем в STL.
G>>Посоветуйте кто какие знает, даже если потокобезопасность идет в ущерб функциональности и универсальности. G>>Уж больно свои делать неохота. Fifo-контейнер нашел, но его мало, а писать самому — боюсь закопаться
КР>Не мучайся этой блажью КР>Синхронизируй доступ к контейнеру извне
КР>Пример КР>пусть у тебя есть враппер над vector в котором во всех методах вставлена синхронизация например по критической секции КР>И что ты думаеш это тебя спасло и ничего делать больше не надо КР>Ошибаешся КР>Где гарантия что после строки 1 не выполнится код Thread2() и не удалит весь контейнер КР>Вывод всю покобезопасность надо реализовать извне а не внутри контейнеров
маленькие коррекции а то быстро писал и наделал ошибок КР>
Здравствуйте, Какая разница, Вы писали:
КР>Здравствуйте, Garrett, Вы писали:
G>>Ищу библиотеку с контейнерами, в которых потокобезопасность получше чем в STL.
G>>Посоветуйте кто какие знает, даже если потокобезопасность идет в ущерб функциональности и универсальности. G>>Уж больно свои делать неохота. Fifo-контейнер нашел, но его мало, а писать самому — боюсь закопаться
КР>Не мучайся этой блажью КР>Синхронизируй доступ к контейнеру извне
Не в моем случае.
Ситуация — два потока. Первый — берет данные из сети и набивает в контейнер (сейчас использую std::hash_map ), его надолго тормозить нельзя. Второй поток занимается медленной обработкой данных, которые лежат в контейнере — поиском и удалением. Его можно и притормозить, если необходимо.
Сейчас вот придумал такую конструкцию — контейнер состоит из входа и базы. На входе — два мелких контейнера, в один из них шустрый поток пихает данные. Как только контейнер заполняется — для напихивания передается второй контейнер, а содержимое первого переливается в основной. Медленный поток
шарится по базовому контейнеру и оперирует с ним. Соответсвенно синхронизировать нужно только момент переключения.
Но уж больно монструозная конструкция получается.
КР>Пример КР>пусть у тебя есть враппер над vector в котором во всех методах вставлена синхронизация например по критической секции КР>И что ты думаеш это тебя спасло и ничего делать больше не надо КР>Ошибаешся КР>Где гарантия что после строки 1 не выполнится код Thread2() и не удалит весь контейнер КР>Вывод всю покобезопасность надо реализовать извне а не внутри контейнеров
Ну, хотелось бы, чтобы по-настоящему потокобезопасный вектор при вызове erase удалил все элементы кроме того, которых захапал it, и ждал, пока it его не освободит. После чего удалил и его.
КР>
Здравствуйте, Garrett, Вы писали:
G>Ищу библиотеку с контейнерами, в которых потокобезопасность получше чем в STL.
G>Посоветуйте кто какие знает, даже если потокобезопасность идет в ущерб функциональности и универсальности. G>Уж больно свои делать неохота. Fifo-контейнер нашел, но его мало, а писать самому — боюсь закопаться
Здравствуйте, Garrett, Вы писали:
G>Ситуация — два потока. Первый — берет данные из сети и набивает в контейнер (сейчас использую std::hash_map ), его надолго тормозить нельзя. Второй поток занимается медленной обработкой данных, которые лежат в контейнере — поиском и удалением. Его можно и притормозить, если необходимо. G>Сейчас вот придумал такую конструкцию — контейнер состоит из входа и базы. На входе — два мелких контейнера, в один из них шустрый поток пихает данные. Как только контейнер заполняется — для напихивания передается второй контейнер, а содержимое первого переливается в основной. Медленный поток G> шарится по базовому контейнеру и оперирует с ним. Соответсвенно синхронизировать нужно только момент переключения. G>Но уж больно монструозная конструкция получается.
Нормально получается. Лочишь оба контейнера, делаешь hash_map::swap и отпускаешь. Все просто и минимальные потери на локе.
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Re[2]: Контейнеры с повышенной потокобезопасностью
От:
Аноним
Дата:
02.11.06 17:38
Оценка:
Здравствуйте, Alexey Frolov, Вы писали:
AF>Здравствуйте, Garrett, Вы писали:
G>>Ищу библиотеку с контейнерами, в которых потокобезопасность получше чем в STL.
G>>Посоветуйте кто какие знает, даже если потокобезопасность идет в ущерб функциональности и универсальности. G>>Уж больно свои делать неохота. Fifo-контейнер нашел, но его мало, а писать самому — боюсь закопаться
AF>Есть такое чудо от microsoft, но насколько оно подойдет решать вам AF>Interlocked Singly Linked Lists
Самое смешное, что даже доступ к этому чуду скорее всего надо будет синхронизировать
Re[4]: Контейнеры с повышенной потокобезопасностью
Здравствуйте, AndrewJD, Вы писали:
AJD>Нормально получается. Лочишь оба контейнера, делаешь hash_map::swap и отпускаешь. Все просто и минимальные потери на локе.
Так в лоб, пожалуй, делать не буду. Сделаю — кину сюда на обсуждение
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Garrett, Вы писали:
G>>Вот, велосипед. Может кому пригодится. А>В таком виде использовать не советую.
А>Вот такие штуки опасны дедлоками, если вдруг между Enter и Leave выскочит исключение. А>
А>EnterCriticalSection(&InputProtector);
А>// bla bla bla
А>LeaveCriticalSection(&InputProtector);
А>
Ну, в этом случае исключений быть не должно. Там же простые операции с заведомо валидным итератором. Конечно, это если пользоваться им как предполагается
А>Используй технику scope quard А>Ну а вообще ты не очень аккуратно делаешь блокировки.
Здравствуйте, Garrett, Вы писали:
G>Вот, велосипед. Может кому пригодится. G>Предполагается, что быстрый поток только кладет данные в контейнер, а медленнй занимается поиском и удалением G>
+ вызвать reserve в векторах чтобы не было realloc
Ну и я бы не так сделал, синхронизация на class C_InputPool ИМХО опять же не нужна вовсе,
лучше бы он был локальным для потока, в конце концов swap делать это не мешает.
Garrett wrote:
> Посоветуйте кто какие знает, даже если потокобезопасность идет в ущерб > функциональности и универсальности.
Далается так:
template<class Container>
struct thread_safe_container
{
boost::mutex m;
Container c;
};
В остальных 90% случаев тебе нужно синхронизировать доступ более чем к одной
переменной (например список + счетчик), поэтому подход использовать один mutex
на одну переменную становится непрактичным, много удобнее использовать один
мьютекс на несколько логически связанных переменных.
По этой причине thread-safe контейнеры часто есть не очень удачная идея.
-- Maxim Yegorushkin
No Microsoft product was used in any way to write or send this text.
If you use a Microsoft product to read it, you're doing so at your own risk
Posted via RSDN NNTP Server 2.0
Re[3]: Контейнеры с повышенной потокобезопасностью
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Alexey Frolov, Вы писали:
AF>>Здравствуйте, Garrett, Вы писали:
G>>>Ищу библиотеку с контейнерами, в которых потокобезопасность получше чем в STL.
G>>>Посоветуйте кто какие знает, даже если потокобезопасность идет в ущерб функциональности и универсальности. G>>>Уж больно свои делать неохота. Fifo-контейнер нашел, но его мало, а писать самому — боюсь закопаться
AF>>Есть такое чудо от microsoft, но насколько оно подойдет решать вам AF>>Interlocked Singly Linked Lists
А>Самое смешное, что даже доступ к этому чуду скорее всего надо будет синхронизировать
все уже украдено до нас (с)
Ничего не надо синхронизировать дополнительно, другое дело, что этот контейнер вряд ли подойдет автору топика, судя по требуемой функциональности. А так я бы назвал его лучшим
Здравствуйте, rm822, Вы писали:
R>Здравствуйте, Garrett, Вы писали:
G>>Вот, велосипед. Может кому пригодится. G>>Предполагается, что быстрый поток только кладет данные в контейнер, а медленнй занимается поиском и удалением G>>
R>+ вызвать reserve в векторах чтобы не было realloc
можно и так, но тогда придется либо делать дополнительные reserve при заполнении вектора, либо переключать и переливать в базовый контейнер в быстром потоке.
R>Ну и я бы не так сделал, синхронизация на class C_InputPool ИМХО опять же не нужна вовсе, R>лучше бы он был локальным для потока, в конце концов swap делать это не мешает.
Не понял... что значит локальным для потока? Поподробнее можно?
Здравствуйте, Garrett, Вы писали:
G>Здравствуйте, rm822, Вы писали:
R>>Здравствуйте, Garrett, Вы писали:
G>>>Вот, велосипед. Может кому пригодится. G>>>Предполагается, что быстрый поток только кладет данные в контейнер, а медленнй занимается поиском и удалением G>>>
R>>+ вызвать reserve в векторах чтобы не было realloc
G>можно и так, но тогда придется либо делать дополнительные reserve при заполнении вектора, либо переключать и переливать в базовый контейнер в быстром потоке.
R>>Ну и я бы не так сделал, синхронизация на class C_InputPool ИМХО опять же не нужна вовсе, R>>лучше бы он был локальным для потока, в конце концов swap делать это не мешает. G>Не понял... что значит локальным для потока? Поподробнее можно?
в таком вот аспекте
C_InputPool& C_InputPool::ThreadInstance()
{
static __declspec( thread ) C_InputPool instance;
return instance;
}
или в таком
void SomeFoo()
{
C_InputPool<....> pool;
.....
}
G>>Не понял... что значит локальным для потока? Поподробнее можно?
R>в таком вот аспекте
R>C_InputPool& C_InputPool::ThreadInstance()
R>{
R> static __declspec( thread ) C_InputPool instance;
R> return instance;
R>}
R>или в таком
R>void SomeFoo()
R>{
R> C_InputPool<....> pool;
R> .....
R>}
R>но не в таком
R>C_InputPool<....> g_pool;
Не догнал идею. :xz:
По-любому экземпляр C_InputPool должен существовать между потоками. Потому как потоку-поставщику некогда делать слив данных из пула в базу.
Вот если потоков несколько, то можно каждому выделить по экземпляру пула... Можно еще заставить APC делать переключение, но до этого уже вряд ли руки дойдут.
G>По-любому экземпляр C_InputPool должен существовать между потоками. Потому как потоку-поставщику некогда делать слив данных из пула в базу.
Ну если поток один зачем ему существовать между? И тем более тогда зачем ему внутри CriticalSection?
Здравствуйте, rm822, Вы писали:
R>Здравствуйте, Garrett, Вы писали:
G>>По-любому экземпляр C_InputPool должен существовать между потоками. Потому как потоку-поставщику некогда делать слив данных из пула в базу. R>Ну если поток один зачем ему существовать между? :) И тем более тогда зачем ему внутри CriticalSection?
Потока как минимум два. Один кладет данные, другой сливает в базу, ищет и удаляет.