如何使用MySQL连接器在c ++中防止打开文件过多

时间:2016-06-13 04:53:32

标签: c++ mysql

它显示错误代码:Can't create socket(24),在我调查后我知道已到达open_files_limit,我检查了show global variables like 'open%'; 在MySQL中,值为5000000,所以我的代码必须有一些问题。

这是我的简单代码:

class DB {
    public:
    double query1();
    double query2();
    double query3();
};

main() {
    DB handler;
    for(int i=0;i<100000;i++) {
        handler.query1();
        handler.query2();
        handler.query3();
    }
}

我写了一个类处理3个查询并在循环中运行它,如何防止这个类中的开放文件限制问题

这是查询代码:

double query1(string pair) { 
    double get_prob;
    try {
        /* Create a connection */
        driver = get_driver_instance();
        con = driver->connect("localhost", "root", "nlpgroup");
        /* Connect to the MySQL test database */
        con->setSchema("em_im");
        stmt = con->createStatement();
        stringstream stmvar;
        stmvar << "select prob from em where pair='" << pair << "'";
        string stmvarstr = stmvar.str();
        cout << stmvarstr << endl;
        res = stmt->executeQuery(stmvarstr); // replace with your statement
        while (res->next()) {
            get_prob = atof(res->getString(1).c_str());
        }
        res->close();
        stmt->close();
        con->close();

        delete res;
        delete stmt;
        delete con;
    } catch (sql::SQLException &e) {
        cout << "# ERR: SQLException in " << __FILE__;
        cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;
        cout << "# ERR: " << e.what();
        cout << " (MySQL error code: " << e.getErrorCode();
        cout << ", SQLState: " << e.getSQLState() << " )" << endl;
    }
    return get_prob;
}

1 个答案:

答案 0 :(得分:1)

  MySQL中的

show global variables like 'open%';

除了MySQL之外,您的操作系统也可能会施加限制。对于Linux,请查看/etc/security/limits.conf,在Windows上,this回答可能对您有帮助。

但是,如果您需要经常一个接一个地使用同一个连接,那么打开它一次并保持打开直到程序终止可能是更好的选择。这将为您提供更好的性能 - 您可以使用预准备语句来提高性能。我已将此添加到下面的示例中......

class DB
{
    std::unique_ptr <sql::Connection> con;
    std::unique_ptr <sql::PreparedStatement> stmt;
public:
    DB();
    double query1(std::string const& pair);
};

DB::DB()
    : con(get_driver_instance()->connect("localhost", "root", "nlpgroup"))
{
    con->setSchema("em_im");
    // you might prefer a prepared statement
    stmt.reset(con->prepareStatement("SELECT prob FROM em WHERE pair = ?"));
}

double DB::query1(std::string const& pair)
{
    double get_prob = 0.0;
    try
    {
        stmt->setString(1, pair);
        std::unique_ptr < sql::ResultSet > res(stmt->execute());
        while (res->next())
        {
            get_prob = atof(res->getString(1).c_str());
        }
    }
    catch(sql::SQLException& e)
    {
        /* ... */
    }
    return get_prob;
}

std::unique_ptr的使用确保即使在异常的情况下也能正确删除所有对象 - 顺便说一下,您的代码没有。我没有明确地调用close - 它会在对象的析构函数中被调用,所以这很好。

请注意,现在构造函数也可以抛出异常,所以你需要在main函数中尝试try - catch。根据您的需要,您可以省略查询功能中的try-catch。但这会改变行为:离开原因导致所有查询都被执行,即使其中一个查询失败,而丢弃它会导致中止循环。