|
|
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
amsdevСкажем так: под некоторые "справочники" будут создаться отдельные таблицы и удаляться при удалении справочника. Для этого используются временные таблицы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.07.2017, 14:46:43 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
авторПри работе с базой данных тип используемого инструмента для блокировок не имеет никакого значения. Все разница в быстродействии исчезнет на фоне работы с данными Ну смотрите, допустим нужно прочитать 3 миллиона записей из таблицы чтобы составить некий сводный отчет. Если мы используем CriticalSection - все остальные клиенты не смогут ни читать, ни писать пока идет чтение данных. А в случае MREW - остальные смогут читать и только некоторые не смогут писать. Поскольку запись у нас реже чтения - это критично. авторТак может просто потоки неправильно настроены? Для SQLite каждый поток должен иметь свое собственное соединение с базой и с включенной опцией мультитрединг. Тут все правильно. Сама дллка собрана с опцией мультитрединг и какждый поток создает свое подключение к базе. Но ограничение на один пишущий поток и на модификацию sqlite_master - это описано в доках sqlite и это (конкретно в нашем случае) нужно разруливать. авторДля этого используются временные таблицы. Насколько я понял из доков Sqlite - временные таблицы удаляются когда закрывается последнее соединение к базе. Т.е. при перезапуске сервера временные таблицы потеряются. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.07.2017, 14:58:01 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
amsdev, я в общем понял, в чем основная проблема... Вам нужен толковый архитектор. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.07.2017, 14:59:56 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
amsdevавторно ведь ты собрался активно выполнять "сreate table/drop table", что мне совсем не нравится. Не активно, нет ! Изредка. Скажем так: под некоторые "справочники" будут создаться отдельные таблицы и удаляться при удалении справочника. Это будет происходить редко - раз в день, а может и раз в месяц. Тем не менее это иногда будет происходить. Когда это происходит - нужно полностью блокировать базу на чтение/запись из других потоков (а по сути - другими клиентами сервера). Как это сделать ? Либо написать свой класс для разграничения доступа к базе, либо в во всем коде, где идет работа с базой делать проверки на busy и lock, ожидания пока блокировка уйдет и повторной попытки выполнить операцию. Мне кажется, что свой класс для разруливания доступа будет проще. Используй FireBird embedded тогда, раз метаданные активно менять не собираешься. А для временных данных - используй GTT. Все вылизано и просто работает. Из разных нитей коннектишься к базе, и просто работаешь с базой, и все. А в случае надобности перейти на удаленный сервер - всего лишь изменишь строку коннекта. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.07.2017, 15:00:11 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
Вот на 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. Все большое спасибо за участие и советы ! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.07.2017, 15:04:24 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
amsdev... Если не получится или вылезут подводные камни - видимо придется таки переходить на FireBird. ...- Скажите, а где тут поезд на Одессу? - Он уже ушел. - Вот бл?*:!, а куда? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.07.2017, 15:19:00 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
В остальном, я думаю, вопрос можно закрывать. Попробуем это:[/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. Поток всех неэксклюзивных врайторидеров: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. Суть такова, что если монопольщику надо писать, то он ставит блокировку и ждет когда все перестанут что-то делать. Все новые не начнут работать, т.к. станут в очередь за мнопольщиком, а все старые спокойно доработают и последний который закончит, выставит FTotalCall в 0 и дернет ивент для монопольщика. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.07.2017, 15:23:12 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
Отдельный поток под запись, которому все будут скидывать задания, нельзя сделать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.07.2017, 15:28:22 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
Большое спасибо ! Попробуем ! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.07.2017, 15:31:23 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
amsdev, после слов - сreate table/drop table - остается только ставить диагноз творцу ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.07.2017, 19:18:31 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
MaratIskamsdev, после слов - сreate table/drop table - остается только ставить диагноз творцуНу и что. Зато сколько драйва. amsdevСвой планировщик нужен для того, чтобы исключить ошибки busy/locked sqlite и таким образом упростить их обработкуВсе, что угодно, лишь бы не разбираться в существующей системе. PS: почему-то вспомнился первый аргумент "сторонников ORM": "не нужно знать SQL"... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.07.2017, 19:32:34 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
Кстати, пишут, что работа с временными ("в памяти" или "отдельный файл") табличками SQLite основной файл базы не блокируется. Хотя, возможно, ТС и к временным табличкам собрался ходить параллельно, из разных потоков... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.07.2017, 19:36:33 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
авторпосле слов - с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 и не контролировать эти ошибки везде в коде где идет работа с базой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.07.2017, 15:18:02 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
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, это ШТАТНОЕ поведение, а не ошибки. И это поведение позволяет продолжить вычислительный процесс, а не перевести в тупое состояние ожидания доступности базы. Ты, если и реализуешь свой "диспетчер", в итоге в придешь к тому же самому (в лучшем случае). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.07.2017, 17:49:53 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
amsdevВы думаете, что create/drop table будет из-за того, что так хочется моей правой ноге ? Нет, все очень внимательно продумывалась и это нужно в силу ряда обстоятельств. И я скажу больше - некоторые большие "справочники" будут в отдельных базах данных т.е. в отдельных файлах, да ) И работа с ними будет через ATTACH DATABASE. Так надо ) Жесть... Еще больше уверен, что нужен толковый архитектор. Либо это саботаж. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.07.2017, 19:10:36 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
amsdev>>это нужно в силу ряда обстоятельств. >>Так надо сразу вспоминается, что примерно так же я отвечал, когда мне указывали на shit-code и предлагали отрефакторить\переписать огромный класс в 300 кб размером, а мне было лень :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.07.2017, 19:18:20 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
авторЖесть... Еще больше уверен, что нужен толковый архитектор. Либо это саботаж. Вы понятия не имеете о специфике задачи, а предлагаете архитекторов, этого не надо. Вопрос был про многоуровневую синхронизацию потоков. Вы в курсе как это сделать наилучшим образом ? Нет ? :-) авторНет никакой "проблемы" с busy/locked, это ШТАТНОЕ поведение, а не ошибки. И это поведение позволяет продолжить вычислительный процесс, а не перевести в тупое состояние ожидания доступности базы. Ты, если и реализуешь свой "диспетчер", в итоге в придешь к тому же самому (в лучшем случае). Может и нет если работать с sqlite api напрямую. Но мы работаем через LiteDac/TDataSet, а для TDataSet это "штатное" поведение не является штатным. Вообще вопрос был про многоуровневую синхронизацию потоков. Sqlite или нет - не имеет значения. Кто-то кроме X-Cite знает как это сделать ? Советчики архитекторов и учителя работать с sqlite не нужны :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.07.2017, 16:13:38 |
|
||
|
Многоуровневая блокировка/синхронизация потоков
|
|||
|---|---|---|---|
|
#18+
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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.07.2017, 18:45:26 |
|
||
|
|

start [/forum/topic.php?fid=58&msg=39489168&tid=2041976]: |
0ms |
get settings: |
7ms |
get forum list: |
13ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
141ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
93ms |
get tp. blocked users: |
1ms |
| others: | 223ms |
| total: | 493ms |

| 0 / 0 |
