2 Stimmen

Verwendung von libmysqlclient in einer Mehrfadenanwendung

Ich erstelle eine C-Anwendung auf der Linux-Plattform. Ich muss libmysqlclient verwenden, um mit der Datenbank zu interagieren.

Ich habe das Linux-Quellcodepaket mysql-connector-c-6.0.2.tar.gz heruntergeladen. Ich habe es gemäß den Anweisungen kompiliert. Ich erhalte die folgenden Bibliotheken:

libmysqlclient.a     libmysqlclient.so  libmysql.so.16
libmysqlclient_r.so  libmysql.so        libmysql.so.16.0.0

Wenn meine Anwendung mehrere Threads hat, kann ich meine Anwendung mit libmysqlclient.a verknüpfen? Laut der MySQL-Dokumentation (http://forge.mysql.com/wiki/Autotools_to_CMake_Transition_Guide) sind Clients mit dem CMake-Tool immer thread-sicher.

Nachdem ich meine Anwendung mit libmysqlclient.a verknüpft habe, stürzt meine Anwendung mit untenstehendem Aufrufstapel ab:

#0  0x0867878a in my_stat ()
Keine Symboltabelleninformationen verfügbar.
#1  0x08671611 in init_available_charsets.clone.0 ()
Keine Symboltabelleninformationen verfügbar.
#2  0x086720d5 in get_charset_by_csname ()
Keine Symboltabelleninformationen verfügbar.
#3  0x086522af in mysql_init_character_set ()
Keine Symboltabelleninformationen verfügbar.
#4  0x0865266d in mysql_real_connect ()

In meiner Anwendung habe ich folgenden Code in der Thread-Funktion:

if (NULL == (pMySQL = mysql_init(NULL)))
{
    return -1;
}

if (NULL == mysql_real_connect(pMySQL, ServerName, UserName, Password, Name, Port, NULL, 0))
{
    mysql_close(pMySQL);
    return -1;  
}

if (0 != mysql_query(pMySQL, pQuery))
{
    mysql_close(pMySQL);
    return -1;
}

mysql_close(pMySQL);

Ich verwende libmysqlclient_r.so nicht, da ich die Verknüpfung mit der MySQL-Clientbibliothek statisch durchführen möchte. Gibt es eine Möglichkeit, libmysqlclient_r.a mit CMake zu generieren?

Aktualisierung:

Ohne etwas anderes zu tun, habe ich einfach den Build-Typ des MySQL-Clients auf Debug geändert. Jetzt stürze ich in der Funktion mysql_init() ab.

Auf der Konsolenanwendung erhalte ich folgende Ausgabe:

safe_mutex: Versuch, uninitialisiertes Mutex bei /install/mysqlconnc/mysql-connector-c-6.0.2/mysys/safemalloc.c, Zeile 520 zu sperren

Der Aufrufstapel des Absturzes sieht wie folgt aus:

#0  0x00556430 in __kernel_vsyscall ()
Keine Symboltabelleninformation verfügbar.
#1  0x45fdf2f1 in raise () von /lib/libc.so.6
Keine Symboltabelleninformation verfügbar.
#2  0x45fe0d5e in abort () von /lib/libc.so.6
Keine Symboltabelleninformation verfügbar.
#3  0x086833e5 in safe_mutex_lock (mp=0x915e8e0, my_flags=0, 
    file=0x895b9d8 "/install/mysqlconnc/mysql-connector-c-6.0.2/mysys/safemalloc.c", line=520)
    at /install/mysqlconnc/mysql-connector-c-6.0.2/mysys/thr_mutex.c:178
        error = 140915306
        __PRETTY_FUNCTION__ = "safe_mutex_lock"
#4  0x08682715 in _sanity ( 
    filename=0x895a87c "/install/mysqlconnc/mysql-connector-c-6.0.2/mysys/my_error.c", lineno=195)
    at /install/mysqlconnc/mysql-connector-c-6.0.2/mysys/safemalloc.c:520
        irem = 0xf2300468
        flag = 0
        count = 0
#5  0x0868186b in _mymalloc (size=16,
    filename=0x895a87c "/install/mysqlconnc/mysql-connector-c-6.0.2/mysys/my_error.c", lineno=195, MyFlags=16)
    at /install/mysqlconnc/mysql-connector-c-6.0.2/mysys/safemalloc.c:130
        irem = 0x0
        data = 0x0
        _db_stack_frame_ = {func = 0x6d617266 

Lösung:

Ich habe einen Aufruf von mysql_library_init() vor der Erstellung der Threads platziert und einen Aufruf von mysql_library_end() nach der Beendigung der Threads platziert. In jedem Thread habe ich einen Aufruf von mysql_thread_init() am Anfang der Thread-Funktion platziert und einen Aufruf von mysql_thread_end() am Ende der Thread-Funktion platziert. Das hat das Problem des Absturzes gelöst.

3voto

vitaut Punkte 42467

Aktualisierung:

Es scheint, dass Sie mysql_library_init() aufrufen müssen, bevor Sie mysql_init() verwenden:

Sie müssen entweder mysql_library_init() aufrufen, bevor Sie Threads erzeugen, oder einen Mutex verwenden, um den Aufruf zu schützen, sei es direkt mysql_library_init() oder indirekt über mysql_init(). Tun Sie dies vor jedem anderen Aufruf der Client-Bibliothek.

Was Ihre ursprüngliche Frage betrifft, ist libmysqlclient_r.so tatsächlich ein symbolischer Link zu libmysql.so. Sie können libmysql/CMakeLists.txt ändern, um eine statische Bibliothek (libmysql.a) zu erstellen, indem Sie das SHARED-Schlüsselwort aus der folgenden Zeile entfernen:

ADD_LIBRARY(libmysql          SHARED ${CLIENT_SOURCES} libmysql.def)

Ich würde jedoch empfehlen, (1) zu versuchen, denselben Code ohne Verwendung von Threads auszuführen und zu sehen, ob das Problem besteht, (2) die Debug-Version der Bibliotheken zu erstellen und zu verwenden:

cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug
make

Auf diese Weise könnten Sie das Problem genauer untersuchen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X