2013-08-02 3 views
6

Ich benutze PostgreSQL 8.3, und schreibe ein Programm in C++, das die libpq API verwendet. Ich führe Befehle asynchron mit der PQsendQuery() Funktion aus. Ich versuche, eine Timeout-Verarbeitungsfunktion zu implementieren. Ich implementierte es, indem ich PQcancel() anrief, wenn das Zeitlimit abläuft. Ich habe es mit einer Abfrage getestet, die 100 000 Zeilen zurückgibt (es dauert etwa 0,5 s) mit einer Zeitüberschreitung von 1 ms und festgestellt, dass PQcancel() blockiert, bis der Server die Ausführung beendet, und dann mit einer erfolgreichen Abfrage zurückkehrt.PostgreSQL: Abfrage abbrechen von C/C++ Programm

Ich verstehe, dass die Dokumentation besagt, dass die Abfrage auch bei einer erfolgreichen Abbruchanforderung weiterhin ausgeführt werden kann. Mein Problem ist, dass PQcancel() blockiert mein Thread der Ausführung, die nicht akzeptabel ist, weil ich asynchrone Verarbeitung (mit dem Boost Asio-Framework) verwenden, so dass mein Programm, das andere Aufgaben als die Ausführung der SQL-Abfrage haben kann, nur auf einem Thread ausgeführt wird .

Ist es normal, dass PQcancel() blockiert? Gibt es eine Möglichkeit, eine nicht blockierende Stornierungsanfrage zu stellen?

+2

Randnotiz: Version 8.3 wird nicht unterstützt. Erwägen Sie, auf eine der unterstützten Versionen zu aktualisieren. –

+0

Es ist die Version, die von der Linux-Distribution geliefert wird, die ich verwende (SUSE 11). – petersohn

+1

Es spielt keine Rolle, wie es versendet wird. Es ist immer noch veraltet. –

Antwort

2

Ich schaute auf die Implementierung von PQcancel. Es erstellt eine separate TCP-Verbindung zum Server, deshalb blockiert es. Dieser Codeteil ist auch in der neuesten Version von PostgreSQL identisch. Also kam ich zu dem Schluss, dass es keinen Weg gibt, es blockfrei zu machen, außer den Absturz in einem separaten Thread zu starten. Dies ist auch die bevorzugte Methode, um diese Funktion zu verwenden, da das cancel-Objekt völlig unabhängig vom Verbindungsobjekt ist und somit absolut threadsicher ist.

0

Es klingt, als ob Sie dies auf einer blockierenden Verbindung tun. Überprüfen Sie die Dokumentation zu PQsetnonblocking, stellen Sie die Verbindung auf nicht blockierend ein und Sie sollten PQCancel sofort zurückgeben können. Aber es macht auch alle Operationen auf der Verbindung nicht blockierend.