powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Многоуровневая блокировка/синхронизация потоков
44 сообщений из 44, показаны все 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
Многоуровневая блокировка/синхронизация потоков
    #39489122
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amsdevСкажем так: под некоторые "справочники" будут создаться отдельные таблицы и удаляться при удалении справочника.
Для этого используются временные таблицы.
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39489139
amsdev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторПри работе с базой данных тип используемого инструмента для блокировок не имеет никакого значения. Все разница в быстродействии исчезнет на фоне работы с данными

Ну смотрите, допустим нужно прочитать 3 миллиона записей из таблицы чтобы составить некий сводный отчет. Если мы используем CriticalSection - все остальные клиенты не смогут ни читать, ни писать пока идет чтение данных. А в случае MREW - остальные смогут читать и только некоторые не смогут писать. Поскольку запись у нас реже чтения - это критично.

авторТак может просто потоки неправильно настроены? Для SQLite каждый поток должен иметь свое собственное соединение с базой и с включенной опцией мультитрединг.

Тут все правильно. Сама дллка собрана с опцией мультитрединг и какждый поток создает свое подключение к базе. Но ограничение на один пишущий поток и на модификацию sqlite_master - это описано в доках sqlite и это (конкретно в нашем случае) нужно разруливать.

авторДля этого используются временные таблицы.

Насколько я понял из доков Sqlite - временные таблицы удаляются когда закрывается последнее соединение к базе. Т.е. при перезапуске сервера временные таблицы потеряются.
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39489144
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amsdev, я в общем понял, в чем основная проблема... Вам нужен толковый архитектор.
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39489145
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amsdevавторно ведь ты собрался активно выполнять "сreate table/drop table", что мне совсем не нравится.

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

Как это сделать ? Либо написать свой класс для разграничения доступа к базе, либо в во всем коде, где идет работа с базой делать проверки на busy и lock, ожидания пока блокировка уйдет и повторной попытки выполнить операцию. Мне кажется, что свой класс для разруливания доступа будет проще.

Используй FireBird embedded тогда, раз метаданные активно менять не собираешься. А для временных данных - используй GTT.
Все вылизано и просто работает.

Из разных нитей коннектишься к базе, и просто работаешь с базой, и все. А в случае надобности перейти на удаленный сервер - всего лишь изменишь строку коннекта.
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39489151
amsdev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот на stackoverflow https://stackoverflow.com/questions/1680249/how-to-use-sqlite-in-a-multi-threaded-application пишут:

Your sqlite3_step, sqlite3_prepare and some other calls may return SQLITE_BUSY or SQLITE_LOCKED. SQLITE_BUSY usually means that sqlite needs to acquire the lock. The biggest difference between the two return values:

SQLITE_LOCKED: if you get this from a sqlite3_step statement, you MUST call sqlite3_reset on the statement handle. You should only get this on the first call to sqlite3_step, so once reset is called you can actually "retry" your sqlite3_step call. On other operations, it's the same as SQLITE_BUSY
SQLITE_BUSY : There is no need to call sqlite3_reset, just retry your operation after waiting a bit for the lock to be released.

Вот ради того чтобы этого избежать все и делается.

В остальном, я думаю, вопрос можно закрывать. Попробуем это:

авторТот который эксклюзивно пишет, вначале делает AtomicIncrement(FWrite) и event.reset в конце AtomicDecrement(FWrite); event.set Остальные вначале делают проверку на if AtomicCmpExchange(FWrite, 0, 0) > 0 then ждем сигнал event
и далее разруливаем TMultiReadExclusiveWriteSynchrinizer

Если не получится или вылезут подводные камни - видимо придется таки переходить на FireBird.

Все большое спасибо за участие и советы !
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39489162
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amsdev...
Если не получится или вылезут подводные камни - видимо придется таки переходить на FireBird.
...- Скажите, а где тут поезд на Одессу?
- Он уже ушел.
- Вот бл?*:!, а куда?
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39489163
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В остальном, я думаю, вопрос можно закрывать. Попробуем это:[/quot]
Только аккуратно, там есть один момент
авторОстальные вначале делают проверку на if AtomicCmpExchange(FWrite, 0, 0) > 0 then ждем сигнал event
Если вдруг отработало сравнение, но еще не дошли до ожидания ивента, а монопольный врайтер опять запустился и процессор переключился и там успел отработать только AtomicIncrement(FWrite) до event.reset.. то будет косяк.
По сути, в остальных потоках до if AtomicCmpExchange(FWrite, 0, 0) > 0 then надо что-то взводить, но так, чтобы монопольный врайтер до AtomicIncrement(FWrite) уже ждал их. Вообщем синхронизация штука сложная, но интересная...
Я бы наверное вот так сделал:
Поток эксклюзивного врайтера:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
  TMonitor.Enter(FLockWrite);
  try
    if AtomicCmpExchange(FTotalCall, 0, 0) > 0 then
      FQueryEmpty.WaitFor(INFINITE);
    // Пишем
  finally
    TMonitor.Exit(FLockWrite);
  end;


Поток всех неэксклюзивных врайторидеров:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
  TMonitor.Enter(FLockWrite);
  try
    AtomicIncrement(FTotalCall);
    FQueueEmpty.ResetEvent();
  finally
    TMonitor.Exit(FLockWrite);
  end;
  try
    // Читаем/Пишем разруливаем их TMultiReadExclusiveWriteSynchrinizer или еще чем между собой.
  finally
    AtomicDecrement(FTotalCall);
    if AtomicCmpExchange(FTotalCall, 0, 0) = 0 then
      FQueueEmpty.SetEvent();
  end;


Суть такова, что если монопольщику надо писать, то он ставит блокировку и ждет когда все перестанут что-то делать.
Все новые не начнут работать, т.к. станут в очередь за мнопольщиком, а все старые спокойно доработают и последний который закончит, выставит FTotalCall в 0 и дернет ивент для монопольщика.
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39489167
Фотография JayDi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Отдельный поток под запись, которому все будут скидывать задания, нельзя сделать?
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39489168
amsdev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Большое спасибо ! Попробуем !
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39489333
MaratIsk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amsdev,
после слов - сreate table/drop table - остается только ставить диагноз творцу
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39489341
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaratIskamsdev,
после слов - сreate table/drop table - остается только ставить диагноз творцуНу и что. Зато сколько драйва.

amsdevСвой планировщик нужен для того, чтобы исключить ошибки busy/locked sqlite и таким образом упростить их обработкуВсе, что угодно, лишь бы не разбираться в существующей системе.

PS: почему-то вспомнился первый аргумент "сторонников ORM": "не нужно знать SQL"...
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39489343
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати, пишут, что работа с временными ("в памяти" или "отдельный файл") табличками SQLite основной файл базы не блокируется.
Хотя, возможно, ТС и к временным табличкам собрался ходить параллельно, из разных потоков...
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39489517
amsdev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторпосле слов - сreate table/drop table - остается только ставить диагноз творцу

Вы думаете, что create/drop table будет из-за того, что так хочется моей правой ноге ? Нет, все очень внимательно продумывалась и это нужно в силу ряда обстоятельств. И я скажу больше - некоторые большие "справочники" будут в отдельных базах данных т.е. в отдельных файлах, да ) И работа с ними будет через ATTACH DATABASE. Так надо )

авторВсе, что угодно, лишь бы не разбираться в существующей системе.

Читаем это:

авторYour sqlite3_step, sqlite3_prepare and some other calls may return SQLITE_BUSY or SQLITE_LOCKED. SQLITE_BUSY usually means that sqlite needs to acquire the lock. The biggest difference between the two return values:

SQLITE_LOCKED: if you get this from a sqlite3_step statement, you MUST call sqlite3_reset on the statement handle. You should only get this on the first call to sqlite3_step, so once reset is called you can actually "retry" your sqlite3_step call. On other operations, it's the same as SQLITE_BUSY
SQLITE_BUSY : There is no need to call sqlite3_reset, just retry your operation after waiting a bit for the lock to be released.

Т.е. возможны два вида ошибок у TQuery.Prepare, TQuery.Open, TQuery.Next и DataBase.StartTransaction/Commit. И в одном случае нужно переоткрыть запрос, а в другом пытаться еще несколько раз по таймеру. Если же самому управлять тем как потоки читают/пишут в базу можно полностью, с гарантией 100% исключить проблемы с busy/locked и не контролировать эти ошибки везде в коде где идет работа с базой.
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39489549
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amsdev...

авторВсе, что угодно, лишь бы не разбираться в существующей системе.

Читаем это:

авторYour sqlite3_step, sqlite3_prepare and some other calls may return SQLITE_BUSY or SQLITE_LOCKED. SQLITE_BUSY usually means that sqlite needs to acquire the lock. The biggest difference between the two return values:

SQLITE_LOCKED: if you get this from a sqlite3_step statement, you MUST call sqlite3_reset on the statement handle. You should only get this on the first call to sqlite3_step, so once reset is called you can actually "retry" your sqlite3_step call. On other operations, it's the same as SQLITE_BUSY
SQLITE_BUSY : There is no need to call sqlite3_reset, just retry your operation after waiting a bit for the lock to be released.

Т.е. возможны два вида ошибок у TQuery.Prepare, TQuery.Open, TQuery.Next и DataBase.StartTransaction/Commit. И в одном случае нужно переоткрыть запрос, а в другом пытаться еще несколько раз по таймеру. Если же самому управлять тем как потоки читают/пишут в базу можно полностью, с гарантией 100% исключить проблемы с busy/locked и не контролировать эти ошибки везде в коде где идет работа с базой.
Нет никакой "проблемы" с busy/locked, это ШТАТНОЕ поведение, а не ошибки. И это поведение позволяет продолжить вычислительный процесс, а не перевести в тупое состояние ожидания доступности базы. Ты, если и реализуешь свой "диспетчер", в итоге в придешь к тому же самому (в лучшем случае).
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39489577
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amsdevВы думаете, что create/drop table будет из-за того, что так хочется моей правой ноге ? Нет, все очень внимательно продумывалась и это нужно в силу ряда обстоятельств. И я скажу больше - некоторые большие "справочники" будут в отдельных базах данных т.е. в отдельных файлах, да ) И работа с ними будет через ATTACH DATABASE. Так надо )

Жесть... Еще больше уверен, что нужен толковый архитектор.
Либо это саботаж.
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39489581
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amsdev>>это нужно в силу ряда обстоятельств.
>>Так надо

сразу вспоминается, что примерно так же я отвечал, когда мне указывали на shit-code и предлагали отрефакторить\переписать огромный класс в 300 кб размером, а мне было лень :)
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39493323
amsdev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторЖесть... Еще больше уверен, что нужен толковый архитектор.
Либо это саботаж.

Вы понятия не имеете о специфике задачи, а предлагаете архитекторов, этого не надо. Вопрос был про многоуровневую синхронизацию потоков. Вы в курсе как это сделать наилучшим образом ? Нет ? :-)

авторНет никакой "проблемы" с busy/locked, это ШТАТНОЕ поведение, а не ошибки. И это поведение позволяет продолжить вычислительный процесс, а не перевести в тупое состояние ожидания доступности базы. Ты, если и реализуешь свой "диспетчер", в итоге в придешь к тому же самому (в лучшем случае).

Может и нет если работать с sqlite api напрямую. Но мы работаем через LiteDac/TDataSet, а для TDataSet это "штатное" поведение не является штатным.

Вообще вопрос был про многоуровневую синхронизацию потоков. Sqlite или нет - не имеет значения. Кто-то кроме X-Cite знает как это сделать ? Советчики архитекторов и учителя работать с sqlite не нужны :-)
...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39493369
Bred eFeM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amsdevВопрос был про многоуровневую синхронизацию потоков.отлично, сколько уровней должно быть?

Если три, то одной внешней (для всех) и ещё одной вложенной (для приоритетных и сверхприоритетных) SRWLock должно хватить.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
Low:

AcquireSRWLockShared(Lo);
 Work();
ReleaseSRWLockShared(Lo);


Norm:

AcquireSRWLockExclusive(Lo);
 AcquireSRWLockShared(Li);
  Work();
 ReleaseSRWLockShared(Li);
ReleaseSRWLockExclusive(Lo);


High:

AcquireSRWLockExclusive(Lo);
 AcquireSRWLockExclusive(Li);
  Work();
 ReleaseSRWLockExclusive(Li);
ReleaseSRWLockExclusive(Lo);

...
Рейтинг: 0 / 0
Многоуровневая блокировка/синхронизация потоков
    #39496781
amsdev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо ! Попробуем !
...
Рейтинг: 0 / 0
44 сообщений из 44, показаны все 2 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Многоуровневая блокировка/синхронизация потоков
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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