(предпочтительно повысить) массив/вектор/карту без блокировки/и т. д.?

Учитывая отсутствие у меня знаний С++, пожалуйста, попробуйте прочитать мои намерения, а не мой плохой технический вопрос.

Это основа моей программы https://github.com/zaphoyd/websocketpp/blob/experimental/examples/broadcast_server/broadcast_server.cpp

Я создаю сервер веб-сокетов с помощью веб-сокета ++ (и, о, веб-сокет ++ сладок. Я настоятельно рекомендую), и я могу легко манипулировать данными пользователя с потокобезопасностью, потому что им действительно не нужно манипулировать разными потоками; однако я хочу иметь возможность писать в массив (я буду использовать универсальный термин «массив» из более слабых языков, таких как vb, php, js) в одном функциональном потоке (с несколькими итерациями, которые могут выполняться одновременно), а также читать в 1 и более потоках.

Возьмем стек в качестве примера: если бы я хотел, чтобы все ids (столбец PRIMARY всех статей) были отсортированы определенным образом, в данном случае по чистым голосам, и хранились в памяти, я думаю, что у меня была бы функция, которая вызывается в своем собственном boost::thread, срабатывающем всякий раз, когда на сайте поступает голосование для изменения порядка массива.

Как я могу сделать это без блокировки и блокировки? Я на 100% согласен с пользователями, читающими из старого массива, в то время как другой строится, но я абсолютно не хочу, чтобы их чтение или запись потока когда-либо терпели неудачу/были заблокированы.

Существует ли массив без блокировок? Если нет, есть ли способ построить новый массив во временном массиве, а затем записать его в фактический массив, когда построение будет завершено без блокировки и блокировки?


person Community    schedule 11.03.2013    source источник
comment
Я не уверен, откуда исходит ваше требование избегать блокировки/блокировки или насколько оно строго, но если вы построили массив во временной структуре данных (в то время как оригинал использовался для доступа), вы могли бы использовать стандартный STL swap(), чтобы поставить его на место после завершения. Это не атомарно, и поэтому потребуется блокировка на время операции подкачки, но это относительно быстрая операция, поэтому ваш массив не будет заблокирован очень долго, и это безопасно. (Что касается вашего вопроса, я лично не знаю, как сделать то, что вы просите, на С++ без блокировки/блокировки.)   -  person Turix    schedule 11.03.2013
comment
(Вы бы хотели использовать шаблон блокировки чтения/записи, если бы реализовали это с помощью swap() согласно моему предыдущему комментарию, кстати.)   -  person Turix    schedule 11.03.2013
comment
Весь этот вопрос кричит мне о преждевременной оптимизации. Вы действительно профилировали свою программу, работающую в реальном сценарии, и показали, что минимальные блокировки, которые вы получите от чего-то вроде подхода @Turix, вызывают проблемы?   -  person Philip Kendall    schedule 12.03.2013


Ответы (2)


Вы смотрели Boost.Lockfree?

person Ferruccio    schedule 11.03.2013

Ух, ух, ух. Сложный.

Посмотрите здесь (для примера): RCU -- и речь идет только о нескольких чтениях вместе с ОДНОЙ записью .

Я предполагаю, что несколько писателей одновременно не сработают. Вам следует искать более эффективное представление, чем массив, которое позволяет выполнять более быстрые обновления. Как насчет сбалансированного дерева? log(n) никогда не должен блокировать что-либо заметным образом.

Что касается повышения - я рад, что наконец-то появилась надлежащая поддержка синхронизации потоков.

Конечно, вы также можете сохранить копию и пакетные обновления. Затем фоновый процесс объединяет обновления и копирует результат для читателей.

person user1050755    schedule 11.03.2013
comment
возможно, попробуйте индекс базы данных. MySQL может хранить таблицы и индексы в оперативной памяти. - person user1050755; 18.03.2013