7

我正在阅读libpq参考资料。它同时具有同步和异步方法。但是我发现了一些奇怪的东西。

当我看到PQsendQuery函数时,它似乎发送了一个查询并立即返回。我希望回调函数会得到通知,但没有这样的事情,手册上说要轮询数据可用性。

我不明白为什么异步方法是以轮询方式编写的。无论如何,正如libp官方客户端实现一样,我相信这种设计应该有充分的理由。那是什么?还是我错过了其他地方提到的正确回调内容?

4

2 回答 2

6

在单线程程序的执行模型中,执行流程不会被从异步查询(或更一般的网络套接字)返回的数据中断。只有信号(SIGTERM和朋友)可能会中断流程,但信号不能与传入的数据挂钩。

这就是为什么无法通过回调来获得传入数据的通知的原因。如果您的代码不调用它,那么发出回调所必需的 libpq 中的一段代码将永远不会运行。如果你必须调用它,那将破坏回调的全部意义。

有类似的库Qt提供回调,但它们是从头开始构建的,具有充当事件处理器的主循环。用户代码以回调的形式组织,并且可以对传入数据进行基于事件的处理。但在这种情况下,库拥有执行流的所有权,这意味着它的主循环会轮询数据源。这只是将责任转移到 libpq 之外的另一段代码。

于 2013-10-13T21:19:02.740 回答
-1

这个页面描述了我如何获得异步结果获取的通知。

http://www.postgresql.org/docs/9.3/static/libpq-events.html#LIBPQ-EVENTS-PROC

PGEVT_RESULTCREATE

结果创建事件被触发以响应任何生成结果的查询执行函数,包括 PQgetResult。只有在成功创建结果后才会触发此事件。

typedef struct { PGconn *conn; PGresult *结果; } PGEventResult创建;当收到 PGEVT_RESULTCREATE 事件时,应该将 evtInfo 指针转换为 PGEventResultCreate *。conn 是用于生成结果的连接。这是初始化需要与结果关联的任何 instanceData 的理想位置。如果事件过程失败,结果将被清除并传播失败。事件过程不能尝试为自己 PQclear 结果对象。返回失败代码时,必须执行所有清理,因为不会发送 PGEVT_RESULTDESTROY 事件。

于 2013-10-12T15:01:36.337 回答