Я использую PostgreSQL 8.3 и пишу программу на C ++, которая использует libpq
API. Я выполняю команды асинхронно с PQsendQuery()
функция. Я пытаюсь реализовать функцию обработки тайм-аута. Я реализовал это, позвонив PQcancel()
когда тайм-аут истекает. Я проверил его с помощью запроса, который возвращает 100 000 строк (это длится около 0,5 с) с таймаутом в 1 мс, и обнаружил, что вместо отмены команды PQcancel()
блокирует, пока сервер не завершит выполнение, затем возвращается с успешным запросом.
Я понимаю, что в документации сказано, что даже при успешном запросе отмены запрос все равно может быть выполнен. Моя проблема в том что PQcancel()
блокирует мой поток выполнения, что недопустимо, потому что я использую асинхронную обработку (используя платформу Boost Asio), поэтому моя программа, которая может выполнять другие задачи, кроме выполнения запроса SQL, выполняется только в одном потоке.
Это нормально, что PQcancel()
блоки? Есть ли способ сделать неблокирующий запрос на отмену?
Я посмотрел на реализацию PQcancel
, Он создает отдельное TCP-соединение с сервером, поэтому он блокируется. Эта часть кода точно такая же, как и в новейшей версии PostgreSQL. Поэтому я пришел к выводу, что нет способа сделать его неблокирующим, кроме как начать отмену в отдельном потоке. Это также предпочтительный способ использования этой функции, так как объект отмены полностью независим от объекта соединения, поэтому он полностью безопасен для потоков.
Похоже, вы делаете это на блокирующем соединении. Проверьте документацию по PQsetnonblocking, установите неблокирующее соединение, и вы сможете получить PQCancel для немедленного возврата. Но это также сделает все операции над соединением неблокирующими.