2013-08-02 10 views
6

Używam PostgreSQL 8.3 i piszę program w C++, który używa interfejsu API libpq. Polecenia wykonuję asynchronicznie z funkcją PQsendQuery(). Próbuję zaimplementować funkcję przetwarzania limitu czasu. Zaimplementowałem go, dzwoniąc pod numer PQcancel() po upływie czasu oczekiwania. Przetestowałem to z zapytaniem, które zwraca 100 000 wierszy (trwa to około 0,5 s) z czasem oczekiwania wynoszącym 1 ms i okazało się, że zamiast anulować polecenie, PQcancel() blokuje do momentu, w którym serwer zakończy wykonywanie, a następnie powróci z pomyślnym zapytaniem.PostgreSQL: anuluj zapytanie z programu C/C++

Rozumiem, że dokumentacja mówi, że nawet po pomyślnym anulowaniu zapytania zapytanie może nadal zostać wykonane. Mój problem polega na tym, że PQcancel() blokuje mój wątek wykonania, co jest niedopuszczalne, ponieważ korzystam z asynchronicznego przetwarzania (używając struktury Boost Asio), więc mój program, który może wykonywać inne zadania niż wykonywanie zapytania SQL, działa tylko w jednym wątku .

Czy to normalne, że blokuje się PQcancel()? Czy istnieje sposób na zrealizowanie niezablokowanego żądania anulowania?

+2

Nota boczna: wersja 8.3 nie jest obsługiwana. Rozważ aktualizację do jednej z obsługiwanych wersji. –

+0

Jest to wersja dostarczana przez dystrybucję Linuksa, której używam (SUSE 11). – petersohn

+1

Nie ma znaczenia, w jaki sposób jest wysyłany. Jest wciąż nieaktualny. –

Odpowiedz

2

Przyjrzałem się realizacji PQcancel. Tworzy oddzielne połączenie TCP z serwerem, dlatego jest blokowane. Ta część kodu jest dokładnie taka sama w najnowszej wersji PostgreSQL. Tak więc doszedłem do wniosku, że nie ma sposobu, aby uczynić go odblokowaniem innym niż rozpoczęcie anulowania w oddzielnym wątku. Jest to również preferowany sposób korzystania z tej funkcji, ponieważ obiekt anulowania jest całkowicie niezależny od obiektu połączenia, dlatego jest całkowicie bezpieczny w użyciu.

0

Wygląda na to, że robisz to na połączeniu blokującym. Sprawdź dokumentację PQsetnonblocking, ustaw połączenie z non-blocking i powinieneś być w stanie uzyskać PQCancel, aby natychmiast powrócił. Ale spowoduje to również, że wszystkie operacje na połączeniu będą blokowane.