如何在libpq(C库)中使用非阻塞连接并触发连接成功回调?
使用libpq非阻塞连接PostgreSQL时触发连接成功回调
针对你的需求,有两种常见实现方式,分别适用于不同场景:
方法1:直接同步触发回调
这是最简单的实现,当循环确认连接成功后,直接调用自定义的回调函数即可:
// 定义回调函数类型 typedef void (*ConnectionSuccessCallback)(PGconn*); // 示例回调函数,可根据需求修改逻辑 void onConnectionSuccess(PGconn* conn) { printf("连接成功!当前数据库:%s\n", PQdb(conn)); // 在这里执行连接成功后的业务逻辑 } int main() { PGconn *conn; PGconnStatusType status; conn = PQconnectStart("dbname=mydatabase user=myusername password=mypassword"); if (conn == NULL) { fprintf(stderr, "连接初始化失败\n"); exit(1); } while ((status = PQconnectPoll(conn)) != CONNECTION_OK) { if (status == PGRES_POLLING_FAILED) { fprintf(stderr, "连接失败: %s\n", PQerrorMessage(conn)); PQfinish(conn); exit(1); } } // 连接成功,立即触发回调 onConnectionSuccess(conn); // 后续数据库操作... PQfinish(conn); return 0; }
方法2:结合事件循环的异步回调(适合多IO任务场景)
如果你的程序本身使用事件循环(如epoll、kqueue、poll),可以通过监听libpq的文件描述符,异步处理连接状态,待连接成功时触发回调:
#include <poll.h> void onConnectionSuccess(PGconn* conn) { printf("异步连接成功!\n"); // 执行连接成功后的逻辑 } int main() { PGconn *conn; PGconnStatusType status; struct pollfd pfd; conn = PQconnectStart("dbname=mydatabase user=myusername password=mypassword"); if (conn == NULL) { fprintf(stderr, "连接初始化失败\n"); exit(1); } status = PQconnectPoll(conn); while (status != CONNECTION_OK) { if (status == PGRES_POLLING_FAILED) { fprintf(stderr, "连接失败: %s\n", PQerrorMessage(conn)); PQfinish(conn); exit(1); } // 获取需要监听的文件描述符和事件类型 pfd.fd = PQsocket(conn); pfd.events = (status == PGRES_POLLING_READING) ? POLLIN : POLLOUT; pfd.revents = 0; // 等待事件触发,不阻塞其他IO任务 if (poll(&pfd, 1, -1) == -1) { perror("poll failed"); PQfinish(conn); exit(1); } // 再次轮询连接状态 status = PQconnectPoll(conn); } // 连接成功触发回调 onConnectionSuccess(conn); // 后续数据库操作... PQfinish(conn); return 0; }
关键说明
- 同步回调适合简单场景,代码简洁直观,无需额外依赖事件循环。
- 异步回调适合需要同时处理多个IO任务的复杂程序,避免阻塞等待连接。
- 回调函数内避免长时间阻塞,防止影响程序其他逻辑的执行。
内容的提问来源于stack exchange,提问作者AmrShams07
相关产品推荐
相关产品推荐

