31.19. 在多线程程序里的行为

libpq是可重入的并且是线程安全的。另外, 在你编译自己的应用代码时,可能需要使用额外的编译器命令行选项。 参考你的系统的文档获取关于如果建立线程可用的应用的信息, 或在src/Makefile.global中查看PTHREAD_CFLAGSPTHREAD_LIBS。此功能允许查询libpq的线程安全状态:

PQisthreadsafe

返回libpq库的线程安全状态。

int PQisthreadsafe();

libpq是线程安全的时,返回1 ;如果不是返回0。

一个线程限制是,两个线程不能试图同时操作同一个PGconn对象。特别是, 你不能从不同的线程里通过同一个连接对象发出并发的命令。(如果你需要运行并行命令, 请使用多个连接。)

PGresult对象在创建后是只读的,因此可以自由地在线程之间传递。然而, 如果你使用在第 31.11 节第 31.13 节 中描述的任何PGresult修改函数,那么它也取决于你可以避免同一 PGresult上的并发操作。

过时了的函数PQrequestCancelPQoidStatus 都是线程不安全的,因此不应该在一个多线程的程序里面使用。PQrequestCancel 可以由PQcancel代替。PQoidStatus可以由 PQoidValue代替。

如果在你的应用内部使用了 Kerberos (而不仅仅是libpq里面), 你就需要在 Kerberos 调用周围锁住,因为 Kerberos 函数不是线程安全的。 参阅libpq源代码里面的PQregisterThreadLock 获取一个在libpq和你的应用之间进行恰当锁定的方法。

如果你的线程应用有问题,那么运行一个在src/tools/thread里的程序, 看看你的平台是否有线程不安全的函数。这个程序由configure运行, 但如果是二进制版本,你的库可能就不能和制作二进制的那个库匹配了。