【问题标题】:Libpqxx connection poollibpqxx 连接池
【发布时间】:2012-09-13 17:43:43
【问题描述】:

我正在尝试使用 libpqxx 库开发一个非常简单直接的连接池。我对 c++ 还是很陌生,仍然对指针和引用感到很困惑。该类的行为非常简单:拥有一个带有一些已初始化连接的向量,并在需要时将连接弹出并推送到该向量上。由于指针和引用的错误实现,代码有很多错误。能给我一些提示吗?

编辑:我设法修复了所有编译错误。当我运行 main 函数时,它给了我一个分段错误。

class DbPool {

公开:

pqxx::result runQuery(const string& query) {

    connection *conn = getCon();
    work trans(*conn);
    result res = trans.exec(query);
    trans.commit();
    releaseCon(conn);

    return res;
}

DbPool(uint32_t max_cons) {

    for (uint32_t i = 0; i < max_cons; i++) {

        connection* con = createCon();
        m_freeCons.push_back(shared_ptr < connection > (con));
    }
}

私人:

connection * createCon() {

    connection * conn =
            new connection(
                    "user='ak' password='rootpassword' dbname='bips_office' hostaddr='127.0.0.1' port='5432'");
    return conn;
}

void releaseCon(connection *con) {

    m_freeCons.push_back(shared_ptr < connection > (con));
}

connection* getCon() {

    shared_ptr < connection > conn = *(m_freeCons.end() - 1);
    m_freeCons.pop_back();
    return conn.get();
}

vector<shared_ptr<connection> > m_freeCons;

};

int main(int argc, char *argv[]) {
     DbPool *pool = new DbPool(5);
     result res = pool->runQuery("SELECT COUNT (*) from captures");
     return 0;
}

【问题讨论】:

  • “代码有很多错误” - 你的意思是编译错误,还是对你的程序运行有影响的运行时错误,或者你的意思是什么?或者你的意思是设计缺陷?请澄清
  • 是的,由于我对指针缺乏经验而导致的设计缺陷导致的编译错误
  • 那么请在这里展示它们!让我们的生活更轻松

标签: c++ libpqxx


【解决方案1】:

如果您担心设计问题,这是我的五分钱:

  • 你的代码真的可以编译吗?我认为不是,因为您有一个 指向连接的指针 的向量,但是您正在推回 connection 对象(m_freeCons.push_back(*con); - * 取消引用 指向连接的指针)...
  • 向成员提供可修改的句柄通常是个坏主意(就像您在 getCon 方法中所做的那样 - 至少,如果可能的话,返回 connection const *
  • 如果您必须使用指针集合,请考虑使用shared_ptr 而不是原始指针 - 这样您就不必担心释放内存;或使用Boost.PointerContainer;另见here
  • 只是一个奇怪的风格问题:你为什么使用return &amp;(*conn)?这会取消引用指针conn,然后再次获取它的地址。相反,您可以简单地写 return conn!

shared_ptrs 回答您重新编写的问题: 您仍然需要使用 new 创建连接,并在其周围包裹一个 shared_ptr;例如对于 createCon:

connection * createCon(){

    connection * conn = new connection("user='ak' password='rootpassword' dbname='bips_office' hostaddr='127.0.0.1' port='5432'");
    return conn;
}

    connection* con = createCon();
    m_freeCons.push_back(shared_ptr<connection>(con));

在其他地方也是如此。

【讨论】:

  • 你知道一些创建shared_ptr向量并执行诸如获取最后一个对象、填充向量和执行push和pop操作的例子
  • 我为您看到的其中一条错误消息添加了一些更正,其他错误消息应该类似,但请查看有关 shared_ptr 的教程,而不是按顺序更新您的问题 - 此站点适用于特定问题一种解决方案,不适用于修复更改和未编译的代码。
  • 我查看了一些教程并设法修复了所有编译错误。你能检查我上面的编辑吗?
  • 好吧,如果它编译正常,运行正常,还有什么要检查的? codereview.stackexchange.com 只是“看着它”
【解决方案2】:

受您帖子的启发,我在自己的项目中使用了这个简单的连接池。我使用了std::stack。推和弹出。添加连接时除了 try-catch 之外没有错误检查。对于 postgresql-db。

数据库.hpp:

#include <stack>
#include <pqxx/pqxx>

class Database {
private:
    const std::string connectionString = "dbname=db user=usr hostaddr=127.0.0.1 port=5432";
    std::stack<pqxx::connection *> dbpool;

public:
    Database(const unsigned int);

数据库.cpp:

#include "Database.hpp"

Database::Database(const unsigned int connections) {
    for (int i = 0; i < connections; ++i) {
        try {
            auto* dbconn = new pqxx::connection(connectionString);
            dbpool.emplace(dbconn);
        } catch (const std::exception& e) {
            std::cerr << e.what() << std::endl;
        }
    }
}

main.cpp:

#include "Database.hpp"

int main(int argc, char* argv[]) {
    Database database {10};

    auto *D = dbpool.top();
    dbpool.pop();

    const std::string query = "select * from mytable";
    pqxx::nontransaction N(*D);
    pqxx::result R(N.exec(query));

    for (pqxx::result::const_iterator c = R.begin(); c != R.end(); ++c) {
        std::cout << c[1].as<std::string>() << std::endl;
    };

    dbpool.push(D);
}

【讨论】:

  • 而不是pqxx::connection 更好地使用pqxx::lazyconnection。你为什么突然出现在 main 中?
  • 我使用 pqxx::connection 立即连接。然后从堆栈获取连接时延迟最小。 top() 为您提供对堆栈中顶部项目的引用,并且 pop() 将其删除。如果您不删除它,另一个连接可能会获得相同的连接。这段代码虽然不是线程安全的,但必须使用互斥锁来实现我在以后的版本中所做的。
猜你喜欢
  • 2013-08-20
  • 1970-01-01
  • 2015-05-02
  • 1970-01-01
  • 2012-01-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多