我正在阅读libpq
参考资料。它同时具有同步和异步方法。但是我发现了一些奇怪的东西。
当我看到PQsendQuery
函数时,它似乎发送了一个查询并立即返回。我希望回调函数会得到通知,但没有这样的事情,手册上说要轮询数据可用性。
我不明白为什么异步方法是以轮询方式编写的。无论如何,正如libp
官方客户端实现一样,我相信这种设计应该有充分的理由。那是什么?还是我错过了其他地方提到的正确回调内容?
我正在阅读libpq
参考资料。它同时具有同步和异步方法。但是我发现了一些奇怪的东西。
当我看到PQsendQuery
函数时,它似乎发送了一个查询并立即返回。我希望回调函数会得到通知,但没有这样的事情,手册上说要轮询数据可用性。
我不明白为什么异步方法是以轮询方式编写的。无论如何,正如libp
官方客户端实现一样,我相信这种设计应该有充分的理由。那是什么?还是我错过了其他地方提到的正确回调内容?
在单线程程序的执行模型中,执行流程不会被从异步查询(或更一般的网络套接字)返回的数据中断。只有信号(SIGTERM
和朋友)可能会中断流程,但信号不能与传入的数据挂钩。
这就是为什么无法通过回调来获得传入数据的通知的原因。如果您的代码不调用它,那么发出回调所必需的 libpq 中的一段代码将永远不会运行。如果你必须调用它,那将破坏回调的全部意义。
有类似的库Qt
提供回调,但它们是从头开始构建的,具有充当事件处理器的主循环。用户代码以回调的形式组织,并且可以对传入数据进行基于事件的处理。但在这种情况下,库拥有执行流的所有权,这意味着它的主循环会轮询数据源。这只是将责任转移到 libpq 之外的另一段代码。
这个页面描述了我如何获得异步结果获取的通知。
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 事件。