Есть ли способ прервать вызов SQLite? - PullRequest
3 голосов
/ 12 октября 2010

Я использую SQLite3 в приложении Windows.У меня есть исходный код (так называемое объединение SQLite).

Иногда мне приходится выполнять тяжелые запросы.То есть я вызываю sqlite3_step для подготовленного оператора, и для его завершения требуется много времени (из-за большой нагрузки ввода-вывода).

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

Я думал о модификации кода SQLite самостоятельно.В простейшем сценарии я мог проверять некоторые условия (например, дескриптор события прерывания) перед каждым вызовом либо ReadFile / WriteFile, и возвращать код ошибки соответствующим образом.И чтобы разрешить фоновую обработку, файл должен быть открыт в режиме наложения (это включает асинхронный ReadFile / WriteFile).

Есть ли вероятность того, что прерывание WriteFile может в некоторых обстоятельствахоставить базу данных в несогласованном состоянии, даже если журнал включен?Думаю, нет, поскольку вся идея файла журнала должна быть подготовлена ​​к любой ошибке любого рода.Но я хотел бы услышать больше мнений по этому поводу.

Кроме того, кто-то пробовал что-то подобное?

Заранее спасибо.

РЕДАКТИРОВАТЬ:

Благодаря ereOn.Я не знал о существовании sqlite3_interrupt.Это, вероятно, отвечает на мой вопрос.

Теперь, для всех вас, кто задается вопросом, как (и почему) можно выполнять некоторую фоновую обработку во время ввода-вывода в пределах одного потока.

К сожалению, нетмногие знакомы с так называемым «перекрывающимся вводом / выводом».

http://en.wikipedia.org/wiki/Overlapped_I/O

Используя его, вы выполняете операцию ввода / вывода асинхронно и вызываетепоток не заблокирован .Затем каждый получает статус завершения ввода / вывода, используя один из механизмов завершения: ожидаемое событие, новая подпрограмма, помещенная в очередь в APC, или порт завершения.

Используя эту технику, не нужно создавать дополнительные потоки.На самом деле единственная реальная легитимация для создания потоков - это когда узким местом является время вычислений (т. Е. Загрузка ЦП), а на машине установлено несколько ЦП (или ядер).

И создание потока простооставлять его заблокированным ОС в большинстве случаев - это не имеет смысла.Это приводит к неоправданной трате ресурсов ОС, усложняет программу (необходимость синхронизации и т. Д.).

К сожалению, не все библиотеки / API допускают асинхронный режим работы, что делает создание дополнительных потоков неизбежно злым.

EDIT2:

Я уже нашел решение, спасибо за внимание.

Для всех тех, кто, тем не менее, настаивает, что это не стоит делатьвещи "в фоновом режиме", в то время как "ожидая" завершения ввода-вывода, используя перекрывающийся ввод-вывод.Я не согласен и думаю, что нет смысла спорить об этом.По крайней мере, это не относится к теме.

Я программист Windows (как вы могли заметить), и у меня очень большой опыт работы во всех видах многозадачности.Кроме того, я также пишу драйверы, так что я также знаю, как все работает "за кулисами".

Я знаю, что это "обычная практика" - создавать несколько потоков, чтобы делать несколько вещей "параллельно",Но это не значит, что это хорошая практика.Пожалуйста, позвольте мне не следовать "обычной практике".

Ответы [ 2 ]

3 голосов
/ 12 октября 2010

Я не понимаю, почему вы хотите, чтобы прерывание исходило от того же потока , и я даже не понимаю, как это было бы возможно: если текущий поток заблокирован, ожидая некоторого ввода-вывода,Вы не можете выполнить любой другой код.(Да, вот что значит «заблокирован»)

Возможно, если вы дадите нам больше подсказок о том, почему вы этого хотите, мы могли бы помочь в дальнейшем.

Обычно я использую sqlite3_interrupt() для отмены звонков.Но это, очевидно, подразумевает, что вызов сделан из другого потока.

1 голос
/ 12 октября 2010

По умолчанию SQLite является поточно-безопасным . Мне кажется, что проще всего было бы запустить команду Sqlite в фоновом потоке и разрешить SQLite установить необходимую блокировку, чтобы эта работа работала.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...