|
|
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
Приветствую ! Подскажите как правильно организовать блокировку/синхронизацию потоков если одновременно возможны следующие сценарии доступа к общим данным: 1. (Часто) Много потоков читают, только один поток может писать - напрашивается использование TMultiReadExclusiveWriteSynchrinizer 2. (Редко) один поток эксклюзивно пишет, все остальные потоки (и пишущие и читающие) ждут. Напрашивается использование TCriticalSection Не совсем понятно каким образом объединить оба сценария в одном планировщике доступа так, чтобы работало максимально быстро и "масштабируемо" ? При чтении данных нужно проверить нет ли эксклюзивной блокировки (тип 2), если есть - ждать, если нет BeginRead/EndRead у TMultiReadExclusiveWriteSynchrinizer При обычной записи данных проверить нет ли эксклюзивной блокировки (тип 2) , если есть - ждать, если нет BeginWrite/EndWrite При эксклюзивной записи данных проверить нет ли эксклюзивной блокировки (тип 2), если есть - ждать, если нет - создать эксклюзивную блокировку, записать, отменить блокировку. Если с обычным чтением-записью вопрос решается через TMultiReadExclusiveWriteSynchrinizer, то как создавать/проверять эксклюзивную блокировку ? Если использовать TCriticalSection то пропадает смысл в использовании TMultiReadExclusiveWriteSynchrinizer т.к. проверку эксклюзивной блокировки нужно делать при каждом доступе к данным хоть на чтение хоть на запись. С другой стороны, эксклюзивная запись будет достаточно редкой. Каким образом организовать работу с эксклюзивной блокировкой чтобы она не слишком мешала ? Interlocked функции, какие-то другие примитивы ? Или может есть какие-то статьи или подходы к таким много уровневым блокировкам ? Спасибо за помощь ! з.ы. Планировщик нужен для многопоточного доступа к БД Sqlite. Мне нужны как обычное чтение-запись в режиме WAL (много читателей, только один писатель), так и эксклюзивная запись когда делаются Create table/drop table и/или модификация служебной таблицы sqlite_master. Свой планировщик нужен для того, чтобы исключить ошибки busy/locked sqlite и таким образом упростить их обработку. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.07.2017, 16:53:07 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
13.07.2017 16:53, amsdev пишет: > Планировщик нужен для многопоточного доступа к БД Sqlite us-us! (C) this made my day Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.07.2017, 17:01:23 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
У sqlite можно выставить флаг, который позволит подключаться к базе только в режиме чтения. А вообще, лучше перейти от нее на нормальную клиент-серверную версию, и не будет таких проблем. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.07.2017, 17:07:26 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
Упс, речь про одно приложение... Тогда в той же OmniThreadLibrary есть разные блокировки и высокоуровневые объекты под разные режимы работы и синхронизации, в которых не надо надрачивать с крит секциями и изобретать велосипеды. http://www.omnithreadlibrary.com ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.07.2017, 17:14:37 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
авторУ sqlite можно выставить флаг, который позволит подключаться к базе только в режиме чтения. А вообще, лучше перейти от нее на нормальную клиент-серверную версию, и не будет таких проблем. Про нормальный бд сервер мы, конечно, думали, но по ряду причин это не подходит. Флаг не решает проблему. авторТогда в той же OmniThreadLibrary есть разные блокировки и высокоуровневые объекты под разные режимы работы и синхронизации Спасибо ! Почитаю их доки ! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.07.2017, 19:37:03 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
Если я правильно понял, то возможно ТС как и я - хотим MREW, но с возможностью VIP прохода, когда нужно как можно скорее записать/почитать экслюзивно (а остальные типа пошли прочь с дороги). В OTL какой это класс? Я постил тут 20371085 экспериментальный, помимо нетестирования бонус-неполадка: если вызвать подряд из одного того же потока BeginRead, затем сразу BeginWrite/Lock то будет dead-lock. Логический тупик. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.07.2017, 19:49:09 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
авторЕсли я правильно понял, то возможно ТС как и я - хотим MREW, но с возможностью VIP прохода Наверно да. Т.е. нужен MREW, но с постоянной проверкой нет ли эксклюзивной (VIP) блокировки. Если VIP блокировки нет - все работает по MREW, а если есть - то все потоки ждут пока VIP разлочится после чего все продолжает работать по MREW. VIP блокировки будут довольно редко, но будут. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.07.2017, 20:01:07 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
Уточню по поводу VIP блокировки как я это понимаю: Если чтение из базы то BeginRead; SELECT * FROM... EndRead; Если обычная запись в базу то BeginWrite; DELETE FROM... EndWrite; Если эксклюзиваня запись: BeginExclusiveWrite; CREATE TABLE SomeTable... EndExclusiveWrite; Таким образом, BeginRead и BeginWrite помимо MREW должны проверять не было ли VIP блокировки (BeginExclusiveWrite). Как эту проверку сделать быстрой и надежной ? Через Interlocked ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.07.2017, 20:06:34 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
amsdev, уровень вопросов и найденного решения такой, что задачу составил человек, далекий от IT. Какая задача изначально? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.07.2017, 20:56:40 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
wadmanamsdev, уровень вопросов и найденного решения такой, что задачу составил человек, далекий от IT. Какая задача изначально? Что тут непонятного. Человек хочет захватить мир, используя SQLite. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.07.2017, 21:19:20 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
Вопрос автору -- в чем разница между записью в базу одним потоком и "критической" записью в базу одним потоком? Ведь и там, и там все остальные будут ждать своей очереди. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.07.2017, 21:21:20 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
чччДwadmanamsdev, уровень вопросов и найденного решения такой, что задачу составил человек, далекий от IT. Какая задача изначально? Что тут непонятного. Человек хочет захватить мир, используя SQLite. Но sqlite и так умеет работать в многопоточке. Я-бы начал с написания ОС, но и тут всё до нас написано. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.07.2017, 21:29:50 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
amsdev... з.ы. Планировщик нужен для многопоточного доступа к БД Sqlite. Мне нужны как обычное чтение-запись в режиме WAL (много читателей, только один писатель), так и эксклюзивная запись когда делаются Create table/drop table и/или модификация служебной таблицы sqlite_master. Свой планировщик нужен для того, чтобы исключить ошибки busy/locked sqlite и таким образом упростить их обработку. Я бы посоветовал вместо SQLite использовать FireBird Embedded, но ведь ты собрался активно выполнять "сreate table/drop table", что мне совсем не нравится. ... А как ты собираешься реализовать параллельный доступ к базе, в которой на лету меняется структура? Ну вот, если одна нить собралась читать что-то писать в табличку, которую вторая нить только что удалила. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.07.2017, 21:30:19 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
Для SQLite многопоточность из коробки реализована (т.е. ничем заморачиваться не надо -- dll-драйвер сам всё обработает как надо). Вот тут подробности есть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.07.2017, 21:36:41 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
amsdevУточню по поводу VIP блокировки как я это понимаю: Если чтение из базы то BeginRead; SELECT * FROM... EndRead; Если обычная запись в базу то BeginWrite; DELETE FROM... EndWrite; Если эксклюзиваня запись: BeginExclusiveWrite; CREATE TABLE SomeTable... EndExclusiveWrite; Таким образом, BeginRead и BeginWrite помимо MREW должны проверять не было ли VIP блокировки (BeginExclusiveWrite). Как эту проверку сделать быстрой и надежной ? Через Interlocked ?Чем вложенные крит. секции не подойдут стандартные? ~5 миллисекунд (иногда) критичны? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.07.2017, 21:46:24 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
amsdev 1. (Часто) Много потоков читают, только один поток может писать - напрашивается использование TMultiReadExclusiveWriteSynchrinizer 2. (Редко) один поток эксклюзивно пишет, все остальные потоки (и пишущие и читающие) ждут. Напрашивается использование TCriticalSection Не совсем понятно каким образом объединить оба сценария в одном планировщике доступа так, чтобы работало максимально быстро и "масштабируемо" ? не понял чем 1 от 2 отличается ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.07.2017, 22:30:37 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
kealon(Ruslan)не понял чем 1 от 2 отличаетсяЕсли будет 2 уровня блокировок, то потоки, устанавливающие блокировку 1-го уровня, будут иметь больше шансов быстрее начать работу с общим ресурсом. Хотя наверно не намного. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.07.2017, 22:38:31 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
YuRockпотоки, устанавливающие блокировку 1-го уровня, будут иметь больше шансов быстрее начать работу Имелись ввиду потоки, которые не блокируются 1-м уровнем, проходят сквозь него. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.07.2017, 23:25:34 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
amsdev, расскажи, пожалуйста, что такое "Свой планировщик" - процедура-функция или отдельный поток или отдельный процесс? https://msdn.microsoft.com/en-us/library/windows/desktop/aa904937(v=vs.85).aspx или самописного аналога на двух AtomicExchange будет достаточно, я думаю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.07.2017, 23:38:08 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
Ну вот что тут обсуждать? Про multi-threaded возможности SQLite выше сказано: http://www.sqlite.org/threadsafe.html http://www.sqlite.org/cvstrac/wiki?p=MultiThreading ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.07.2017, 23:49:09 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
авторто как создавать/проверять эксклюзивную блокировку Тот который эксклюзивно пишет, вначале делает AtomicIncrement(FWrite) и event.reset в конце AtomicDecrement(FWrite); event.set Остальные вначале делают проверку на if AtomicCmpExchange(FWrite, 0, 0) > 0 then ждем сигнал event и далее разруливаем TMultiReadExclusiveWriteSynchrinizer ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.07.2017, 01:00:11 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
авторуровень вопросов и найденного решения такой, что задачу составил человек, далекий от IT. Какая задача изначально? Задача следующая: разрабатывается сервер, предоставляющий API через json-rpc. В качестве движка БД планируется использовать Sqlite т.к. она не требует настройки, не зависима от ОС и не может конфликтовать с сервером БД, который может быть установлен у пользователя. Изначально хотели использовать MySQL или FireBird, но не хочется иметь никаких проблем с деплоем и возможными конфликтами. авторЧто тут непонятного. Человек хочет захватить мир, используя SQLite. Захватить мир - это, пожалуй, слишком абмициозно ))) Нет, хочется решить поставленную задачу по возможности малой кровью. На данный момент непреодолимых проблем вроде не видно. авторВопрос автору -- в чем разница между записью в базу одним потоком и "критической" записью в базу одним потоком? Ведь и там, и там все остальные будут ждать своей очереди. Смысл в следующем: Sqlite в режиме WAL позволяет параллельно читать данные из множества потоков и писать данные, но только одним потоком. Таким образом нужно чтобы чтение работало параллельно, а запись - через блокировку. Т.е. тут поможет MREW. Однако, некоторые операции (такие как create table/alter table/drop table а так же модификация таблицы sqlite_master) полностью блокируют и читателей и писателей (ну точнее приведут к ошибкам sqlite_busy и/или sqlite_locked). Таким образом, для этих операций нужна эксклюзивная блокировка когда никакие другие потоки не могут не читать, не писать пока текущий поток не завершит транзакцию. В этом случае нужна критическая секция. Вопрос в том, как совместить MREW и критическую секцию чтобы не убить возможность параллельного чтения ? Ведь эксклюзивные операция выполняются очень редко, а чтение и простая запись - часто. авторНо sqlite и так умеет работать в многопоточке. Умеет, да не совсем. Скажем так, нужно постоянно обрабатывать возможные ошибки busy/locked во всех местах где идет работа с базой. BusyTimeout тоже работает с ограничениями. Цель в том, чтобы разруливать два типа блокировок самостоятельно, что приведет к отсутствию необходимости отлавливать эти ошибки в 500 местах. авторЧем вложенные крит. секции не подойдут стандартные? ~5 миллисекунд (иногда) критичны? Тем, что чтение из базы будет по сути в один поток, а это не очень хорошо. Конечно, транзакции стараемся сделать максимально короткими, но тем не менее иногда нужно довольно много читать из большой таблицы. Да, это 3-4 секунды, но в случае критических секций эти 3-4 секунды будут выглядеть как фриз сервера. авторне понял чем 1 от 2 отличается Тем что 2 требует полной блокировки всей БД на время пока создаются/удаляются таблицы или модифицируется sqlite_master. Пока это происходит - из базы нельзя вообще не читать, не писать. авторрасскажи, пожалуйста, что такое "Свой планировщик" - процедура-функция или отдельный поток или отдельный процесс? Свой планировщик это условно вот-что: BeginRead; SELECT * FROM... EndRead; Если обычная запись в базу то BeginWrite; DELETE FROM... EndWrite; Если эксклюзиваня запись: BeginExclusiveWrite; CREATE TABLE SomeTable... EndExclusiveWrite; BeginRead работает параллельно, BeginWrite - может быть только один, BeginExclusiveWrite - пока установлен то запрещены BeginRead и BeginWrite. авторТот который эксклюзивно пишет, вначале делает AtomicIncrement(FWrite) и event.reset в конце AtomicDecrement(FWrite); event.set Остальные вначале делают проверку на if AtomicCmpExchange(FWrite, 0, 0) > 0 then ждем сигнал event и далее разруливаем TMultiReadExclusiveWriteSynchrinizer ДА ! ДА ! ДА ! Я именно об этом спрашивал ) В данном случае Atomic/Interlocked функции+MREW будут самым эффективным решением ? Или есть какие-то более продвинутые техники (примитивы) синхронизации ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.07.2017, 14:21:09 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
авторно ведь ты собрался активно выполнять "сreate table/drop table", что мне совсем не нравится. Не активно, нет ! Изредка. Скажем так: под некоторые "справочники" будут создаться отдельные таблицы и удаляться при удалении справочника. Это будет происходить редко - раз в день, а может и раз в месяц. Тем не менее это иногда будет происходить. Когда это происходит - нужно полностью блокировать базу на чтение/запись из других потоков (а по сути - другими клиентами сервера). Как это сделать ? Либо написать свой класс для разграничения доступа к базе, либо в во всем коде, где идет работа с базой делать проверки на busy и lock, ожидания пока блокировка уйдет и повторной попытки выполнить операцию. Мне кажется, что свой класс для разруливания доступа будет проще. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.07.2017, 14:30:04 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
amsdevВ данном случае Atomic/Interlocked функции+MREW будут самым эффективным решением ?При работе с базой данных тип используемого инструмента для блокировок не имеет никакого значения. Все разница в быстродействии исчезнет на фоне работы с данными ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.07.2017, 14:37:53 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
amsdevУмеет, да не совсем. Скажем так, нужно постоянно обрабатывать возможные ошибки busy/locked во всех местах где идет работа с базой. Так может просто потоки неправильно настроены? Для SQLite каждый поток должен иметь свое собственное соединение с базой и с включенной опцией мультитрединг. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.07.2017, 14:39:20 |
|
||
|
|

start [/forum/topic.php?fid=58&msg=39488713&tid=2041976]: |
0ms |
get settings: |
8ms |
get forum list: |
17ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
188ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
71ms |
get tp. blocked users: |
1ms |
| others: | 183ms |
| total: | 487ms |

| 0 / 0 |
