31.21. Поведение в многопоточных программах#

31.21. Поведение в многопоточных программах

31.21. Поведение в многопоточных программах #

Начиная с версии 17, libpq всегда является повторно входящей и потокобезопасной. Однако одно ограничение заключается в том, что ни один из двух потоков не должен пытаться манипулировать одним и тем же объектом PGconn одновременно. В частности, вы не можете выполнять параллельные команды из разных потоков через один и тот же объект соединения. (Если вам нужно выполнять параллельные команды, используйте несколько соединений.)

Объекты PGresult обычно доступны только для чтения после создания и могут свободно передаваться между потоками. Однако, если вы используете любые из функций изменения PGresult, описанных в Раздел 31.12 или Раздел 31.14, необходимо избегать одновременных операций с одним и тем же PGresult.

В более ранних версиях, libpq мог быть скомпилирован с поддержкой потоков или без нее, в зависимости от опций компилятора. Эта функция позволяет узнать статус потокобезопасности libpq:

PQisthreadsafe #

Возвращает статус потокобезопасности библиотеки libpq.

int PQisthreadsafe();

Возвращает 1, если libpq является потокобезопасным, и 0, если нет. Всегда возвращает 1 в версии 17 и выше.

Устаревшие функции PQrequestCancel и PQoidStatus не являются потокобезопасными и не должны использоваться в многопоточных программах. PQrequestCancel может быть заменена на PQcancelBlocking. PQoidStatus может быть заменена на PQoidValue.

Если вы используете Kerberos внутри вашего приложения (в дополнение к использованию внутри библиотеки libpq), вам потребуется выполнять блокировку вокруг вызовов Kerberos, поскольку функции Kerberos не являются потокобезопасными. См. функцию PQregisterThreadLock в исходном коде библиотеки libpq для способа совместной блокировки между libpq и вашим приложением.

Аналогично, если вы используете Curl в вашем приложении, и вы еще не инициализировали libcurl глобально перед запуском новых потоков, вам нужно будет кооперативно блокировать (снова через PQregisterThreadLock) любой код, который может инициализировать libcurl. Это ограничение снимается для более новых версий Curl, которые построены с поддержкой потокобезопасной инициализации; такие сборки можно идентифицировать по наличию threadsafe функции в их метаданных версии.