2013-10-13 67 views
2

我目前正在開發一個使用數據庫連接的小型C++程序。 它是通過CPPCONN連接器與MySQL數據庫的連接。MySQL cppconn線程分段錯誤

原因

我使用多線程和爲此我創建了以下方法:

void Database::startThread() 
{ 
    fDriver->threadInit(); 
} 

void Database::stopThread() 
{ 
    fDriver->threadEnd(); 
} 

void Database::connect(const string & host, const string & user, const string & password, const string & database) 
{ 
     fDriver = sql::mysql::get_driver_instance(); 
     fConnection.reset(fDriver->connect((SQLString)host,(SQLString)user,(SQLString)password)); 
     fConnection->setSchema((SQLString) database); 
     fStatement.reset(fConnection->createStatement()); 
     fConnection->setClientOption("multi-queries","true"); 
     fConnection->setClientOption("multi-statements","true"); 
} 

的問題是,我遇到分割故障在fDriver-> threadInit()調用。 我可以向你保證,fDriver通過connect函數在那一點正確實例化了。 (fDriver不爲空或者)

崩潰

不幸的是,我不能給更多有用的信息,但是這是GDB的回溯:

Program received signal SIGSEGV, Segmentation fault. 
[Switching to Thread 0x7ffff4d66700 (LWP 16786)] 
0x0000000000414547 in Database::startThread (this=Unhandled dwarf expression opcode 0xf3 
#0 0x0000000000414547 in Database::startThread (this=Unhandled dwarf expression opcode 0xf3) at src/core/database.cpp:73 
#1 0x0000000000405443 in Parser::Parser (this=0x7ffff4d659b8) at src/core/sv_parse.cpp:11 
#2 0x000000000041e76d in MessageProcessor::MessageProcessor (this=0x7ffff4d659b0, serverStartTime=...) at src/server/messageProcessor.cpp:12 
#3 0x000000000041bae8 in Server::__lambda1::operator() (__closure=0x62c740) at src/server/server.cpp:89 
#4 0x00007ffff763f550 in execute_native_thread_routine() at ../../../../../libstdc++-v3/src/c++11/thread.cc:84 
#5 0x00007ffff6edb851 in start_thread() from /lib64/libpthread.so.0 
#6 0x00007ffff6c2994d in clone() from /lib64/libc.so.6 

備註

現在奇怪的部分:這種崩潰不會一直髮生! 有時它可以完美運作。 但是,如果沒有,這當然是非常煩人的。 CPPCONN版本是1.1.3,我們使用的是g ++版本4.8.1。

我希望有人能夠揭示這個謎團!

Giriel

回答

3

我掙扎了好幾個小時,出現了相同的神祕分割錯誤。 我發現在get_driver_instance()周圍添加互斥鎖解決了這個問題。 這是一個線程函數的基本框架。這適用於從數據庫中進行選擇,可能無法用於插入或更新。

#include <mutex> 

std::mutex mtx; 

void test() 
{ 
    sql::Driver *driver; 
    sql::Connection *con; 

    try { 
    mtx.lock(); 
    driver = get_driver_instance(); 
    mtx.unlock(); 
    driver->threadInit(); 
    con = driver->connect(HOST, USER, PASS); 
    ... 
    con->close(); 
    driver->threadEnd(); 
    } catch(...) { ... } 
} 
+0

您好,感謝您的意見!我會放棄這一點。 – giriel