You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 04:55:19