PostgreSQL: 从C/C++程序取消查询

9
我正在使用 PostgreSQL 8.3,并编写一个使用 libpq API 的 C++ 程序。我使用 PQsendQuery() 函数异步执行命令。我正试图实现一个超时处理特性。当超时到期时,我通过调用 PQcancel() 来实现它。我使用一个返回 100,000 行的查询进行测试(持续约 0.5 秒),并设置了 1 毫秒的超时时间,发现与其取消命令,PQcancel() 阻塞直到服务器完成执行,然后以成功的查询返回。
我知道文档中说即使有成功的取消请求,查询仍可能被执行。我的问题在于,PQcancel() 阻塞了我的执行线程,这是不可接受的,因为我使用异步处理(使用 Boost Asio 框架),所以我的程序可能还有其他任务要执行,而不仅仅是执行 SQL 查询,只能运行在一个线程上。
PQcancel() 阻塞是正常的吗?有没有办法进行非阻塞式的取消请求?

2
附注:不支持8.3版本。请考虑升级到其中一个受支持的版本。 - Ihor Romanchenko
这是我使用的Linux发行版(SUSE 11)提供的版本。 - petersohn
1
无论如何它被运送,它仍然过时。 - Ihor Romanchenko
只有在较新版本中 PQcancel() 的功能不同,才会对当前产生影响。 - petersohn
仍然适用于9.4版本。 - YSC
目前正在进行中 https://commitfest.postgresql.org/38/3511/ - Eelke
2个回答

4

我看了一下 PQcancel 的实现。它会创建一个单独的 TCP 连接到服务器,这就是为什么它是阻塞的原因。在最新版本的 PostgreSQL 中,这部分代码也完全相同。所以我得出结论,除了在单独的线程中启动取消操作外,没有其他方法使其非阻塞。这也是使用此功能的首选方式,因为取消对象与连接对象完全独立,因此可以完全线程安全地使用。


0

听起来你正在使用阻塞连接。请查看PQsetnonblocking的文档,将连接设置为非阻塞,这样你就可以立即获得PQCancel的返回值。但是这也会使连接上的所有操作变成非阻塞。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接