PostgreSQL 中文参考文档
🌐 英文原版 官方 ↗

32.21. 在多线程程序中的并发行为 #

从版本 17 起, libpq 总是可重入且线程安全的。 然而, 有一项限制是: 不允许两个线程同时操纵同一个 PGconn 对象。 特别是, 你不能从不同的线程通过同一个连接对象发出并发的命令。 (如果你需要运行并发命令, 请使用多条连接。)

PGresult 对象在创建之后通常是只读的, 因此可以在线程之间自由传递。 然而, 如果你使用 Section 32.12 或 Section 32.14 中描述的任何修改 PGresult 的函数, 那么避免对同一个 PGresult 进行并发操作也是你的责任。

在较早的版本中, libpq 可以根据编译器选项选择带或不带线程支持进行编译。 这个函数允许查询 libpq 的线程安全状态:

PQisthreadsafe #

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

int PQisthreadsafe();

如果 libpq 是线程安全的则返回 1, 否则返回 0。 在版本 17 及更高版本上它总是返回 1。

已弃用的函数 PQrequestCancel 和 PQoidStatus 不是线程安全的, 不应当在多线程程序中使用。 PQrequestCancel 可以被 PQcancelBlocking 取代。 PQoidStatus 可以被 PQoidValue 取代。

如果你在应用程序内部 (除了在 libpq 内部之外) 使用 Kerberos, 你将需要在 Kerberos 调用周围加锁, 因为 Kerberos 函数不是线程安全的。 有关在 libpq 与你的应用程序之间进行协作式加锁的一种方法, 请参见 libpq 源代码中的函数 PQregisterThreadLock。

类似地, 如果你在应用程序内部使用 Curl, 并且你还没有在启动新线程之前 全局初始化 libcurl, 那么你将需要在任何可能初始化 libcurl 的代码周围进行协作式加锁 (同样通过 PQregisterThreadLock)。 这一限制在…… (如 m 变体那样) (译注:该句按英文原文转录)