powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Многоуровневая блокировка/синхронизация потоков
25 сообщений из 44, страница 1 из 2
Многоуровневая блокировка/синхронизация потоков
    #39488576
amsdev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Приветствую !

Подскажите как правильно организовать блокировку/синхронизацию потоков если одновременно возможны следующие сценарии доступа к общим данным:

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 и таким образом упростить их обработку.
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39488583
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
13.07.2017 16:53, amsdev пишет:
> Планировщик нужен для многопоточного доступа к БД Sqlite

us-us! (C)

this made my day
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39488585
Фотография JayDi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У sqlite можно выставить флаг, который позволит подключаться к базе только в режиме чтения. А вообще, лучше перейти от нее на нормальную клиент-серверную версию, и не будет таких проблем.
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39488589
Фотография JayDi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Упс, речь про одно приложение... Тогда в той же OmniThreadLibrary есть разные блокировки и высокоуровневые объекты под разные режимы работы и синхронизации, в которых не надо надрачивать с крит секциями и изобретать велосипеды.

http://www.omnithreadlibrary.com
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39488669
amsdev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторУ sqlite можно выставить флаг, который позволит подключаться к базе только в режиме чтения. А вообще, лучше перейти от нее на нормальную клиент-серверную версию, и не будет таких проблем.

Про нормальный бд сервер мы, конечно, думали, но по ряду причин это не подходит.

Флаг не решает проблему.

авторТогда в той же OmniThreadLibrary есть разные блокировки и высокоуровневые объекты под разные режимы работы и синхронизации

Спасибо ! Почитаю их доки !
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39488680
Кар-Кар
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если я правильно понял, то возможно ТС как и я - хотим MREW, но с возможностью VIP прохода, когда нужно как можно скорее записать/почитать экслюзивно (а остальные типа пошли прочь с дороги).

В OTL какой это класс?

Я постил тут 20371085 экспериментальный, помимо нетестирования бонус-неполадка: если вызвать подряд из одного того же потока BeginRead, затем сразу BeginWrite/Lock то будет dead-lock. Логический тупик.
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39488682
amsdev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторЕсли я правильно понял, то возможно ТС как и я - хотим MREW, но с возможностью VIP прохода

Наверно да. Т.е. нужен MREW, но с постоянной проверкой нет ли эксклюзивной (VIP) блокировки. Если VIP блокировки нет - все работает по MREW, а если есть - то все потоки ждут пока VIP разлочится после чего все продолжает работать по MREW.

VIP блокировки будут довольно редко, но будут.
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39488685
amsdev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Уточню по поводу VIP блокировки как я это понимаю:

Если чтение из базы то

BeginRead;
SELECT * FROM...
EndRead;

Если обычная запись в базу то

BeginWrite;
DELETE FROM...
EndWrite;

Если эксклюзиваня запись:

BeginExclusiveWrite;
CREATE TABLE SomeTable...
EndExclusiveWrite;

Таким образом, BeginRead и BeginWrite помимо MREW должны проверять не было ли VIP блокировки (BeginExclusiveWrite). Как эту проверку сделать быстрой и надежной ? Через Interlocked ?
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39488701
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amsdev,

уровень вопросов и найденного решения такой, что задачу составил человек, далекий от IT.

Какая задача изначально?
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39488712
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanamsdev,

уровень вопросов и найденного решения такой, что задачу составил человек, далекий от IT.

Какая задача изначально?
Что тут непонятного. Человек хочет захватить мир, используя SQLite.
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39488713
Фотография JayDi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вопрос автору -- в чем разница между записью в базу одним потоком и "критической" записью в базу одним потоком? Ведь и там, и там все остальные будут ждать своей очереди.
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39488717
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чччДwadmanamsdev,

уровень вопросов и найденного решения такой, что задачу составил человек, далекий от IT.

Какая задача изначально?
Что тут непонятного. Человек хочет захватить мир, используя SQLite.
Но sqlite и так умеет работать в многопоточке.

Я-бы начал с написания ОС, но и тут всё до нас написано.
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39488718
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amsdev...
з.ы. Планировщик нужен для многопоточного доступа к БД Sqlite. Мне нужны как обычное чтение-запись в режиме WAL (много читателей, только один писатель), так и эксклюзивная запись когда делаются Create table/drop table и/или модификация служебной таблицы sqlite_master. Свой планировщик нужен для того, чтобы исключить ошибки busy/locked sqlite и таким образом упростить их обработку.
Я бы посоветовал вместо SQLite использовать FireBird Embedded, но ведь ты собрался активно выполнять "сreate table/drop table", что мне совсем не нравится.
...
А как ты собираешься реализовать параллельный доступ к базе, в которой на лету меняется структура? Ну вот, если одна нить собралась читать что-то писать в табличку, которую вторая нить только что удалила.
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39488722
Фотография JayDi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для SQLite многопоточность из коробки реализована (т.е. ничем заморачиваться не надо -- dll-драйвер сам всё обработает как надо). Вот тут подробности есть.
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39488727
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amsdevУточню по поводу VIP блокировки как я это понимаю:

Если чтение из базы то

BeginRead;
SELECT * FROM...
EndRead;

Если обычная запись в базу то

BeginWrite;
DELETE FROM...
EndWrite;

Если эксклюзиваня запись:

BeginExclusiveWrite;
CREATE TABLE SomeTable...
EndExclusiveWrite;

Таким образом, BeginRead и BeginWrite помимо MREW должны проверять не было ли VIP блокировки (BeginExclusiveWrite). Как эту проверку сделать быстрой и надежной ? Через Interlocked ?Чем вложенные крит. секции не подойдут стандартные? ~5 миллисекунд (иногда) критичны?
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39488740
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amsdev
1. (Часто) Много потоков читают, только один поток может писать - напрашивается использование TMultiReadExclusiveWriteSynchrinizer

2. (Редко) один поток эксклюзивно пишет, все остальные потоки (и пишущие и читающие) ждут. Напрашивается использование TCriticalSection

Не совсем понятно каким образом объединить оба сценария в одном планировщике доступа так, чтобы работало максимально быстро и "масштабируемо" ?
не понял чем 1 от 2 отличается
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39488742
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)не понял чем 1 от 2 отличаетсяЕсли будет 2 уровня блокировок, то потоки, устанавливающие блокировку 1-го уровня, будут иметь больше шансов быстрее начать работу с общим ресурсом. Хотя наверно не намного.
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39488760
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockпотоки, устанавливающие блокировку 1-го уровня, будут иметь больше шансов быстрее начать работу
Имелись ввиду потоки, которые не блокируются 1-м уровнем, проходят сквозь него.
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39488761
Bred eFeM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amsdev, расскажи, пожалуйста, что такое "Свой планировщик" - процедура-функция или отдельный поток или отдельный процесс?

https://msdn.microsoft.com/en-us/library/windows/desktop/aa904937(v=vs.85).aspx или самописного аналога на двух AtomicExchange будет достаточно, я думаю.
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39488764
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну вот что тут обсуждать? Про multi-threaded возможности SQLite выше сказано:

http://www.sqlite.org/threadsafe.html
http://www.sqlite.org/cvstrac/wiki?p=MultiThreading
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39488770
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторто как создавать/проверять эксклюзивную блокировку
Тот который эксклюзивно пишет, вначале делает AtomicIncrement(FWrite) и event.reset в конце AtomicDecrement(FWrite); event.set
Остальные вначале делают проверку на if AtomicCmpExchange(FWrite, 0, 0) > 0 then ждем сигнал event
и далее разруливаем TMultiReadExclusiveWriteSynchrinizer
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39489106
amsdev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторуровень вопросов и найденного решения такой, что задачу составил человек, далекий от 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 будут самым эффективным решением ? Или есть какие-то более продвинутые техники (примитивы) синхронизации ?
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39489110
amsdev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторно ведь ты собрался активно выполнять "сreate table/drop table", что мне совсем не нравится.

Не активно, нет ! Изредка. Скажем так: под некоторые "справочники" будут создаться отдельные таблицы и удаляться при удалении справочника. Это будет происходить редко - раз в день, а может и раз в месяц. Тем не менее это иногда будет происходить. Когда это происходит - нужно полностью блокировать базу на чтение/запись из других потоков (а по сути - другими клиентами сервера).

Как это сделать ? Либо написать свой класс для разграничения доступа к базе, либо в во всем коде, где идет работа с базой делать проверки на busy и lock, ожидания пока блокировка уйдет и повторной попытки выполнить операцию. Мне кажется, что свой класс для разруливания доступа будет проще.
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39489116
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amsdevВ данном случае Atomic/Interlocked функции+MREW будут самым эффективным решением ?При работе с базой данных тип используемого инструмента для блокировок не имеет никакого значения. Все разница в быстродействии исчезнет на фоне работы с данными
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39489117
Фотография JayDi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amsdevУмеет, да не совсем. Скажем так, нужно постоянно обрабатывать возможные ошибки busy/locked во всех местах где идет работа с базой.
Так может просто потоки неправильно настроены? Для SQLite каждый поток должен иметь свое собственное соединение с базой и с включенной опцией мультитрединг.
...
Рейтинг: 0 / 0
25 сообщений из 44, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Многоуровневая блокировка/синхронизация потоков
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]