mysql - 在多线程应用程序中使用 libmysqlclient

标签 mysql c linux cmake

我正在 Linux 平台上构建一个 C 应用程序。我需要使用 libmysqlclient 来连接数据库。

我下载了Linux源代码包mysql-connector-c-6.0.2.tar.gz。我按照说明编译了它。我得到以下库:

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

如果我的应用程序是多线程的,我可以将我的应用程序与 libmysqlclient.a 链接吗?根据 mysql 文档 ( http://forge.mysql.com/wiki/Autotools_to_CMake_Transition_Guide ),使用 cmake 工具,客户端始终是线程安全的。

将我的应用程序与 libmysqlclient.a 链接后,我的应用程序发生崩溃,调用堆栈如下:

#0  0x0867878a in my_stat ()
No symbol table info available.
#1  0x08671611 in init_available_charsets.clone.0 ()
No symbol table info available.
#2  0x086720d5 in get_charset_by_csname ()
No symbol table info available.
#3  0x086522af in mysql_init_character_set ()
No symbol table info available.
#4  0x0865266d in mysql_real_connect ()

在我的应用程序中,线程函数中有以下代码:

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);

我没有使用 libmysqlclient_r.so,因为我想静态链接到 mysql 客户端库。有没有办法用cmake生成libmysqlclient_r.a?

更新:

没有做任何其他事情,我只是将 mysql 客户端构建类型更改为调试。现在我在 mysql_init() 函数中崩溃了。

在应用程序控制台上,我得到以下打印:

safe_mutex: Trying to lock unitialized mutex at /install/mysqlconnc/mysql-connector-c-6.0.2/mysys/safemalloc.c, line 520

崩溃的调用堆栈如下:

#0  0x00556430 in __kernel_vsyscall ()
No symbol table info available.
#1  0x45fdf2f1 in raise () from /lib/libc.so.6
No symbol table info available.
#2  0x45fe0d5e in abort () from /lib/libc.so.6
No symbol table info available.
#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 <Address 0x6d617266 out of bounds>, file = 0x65685f65 <Address 0x65685f65 out of bounds>,
          level = 0, prev = 0x0}
#6  0x0867e0e1 in my_error_register (errmsgs=0x89a7760, first=2000, last=2058)
    at /install/mysqlconnc/mysql-connector-c-6.0.2/mysys/my_error.c:194
        meh_p = 0x46087568
        search_meh_pp = 0x1000
#7  0x08655f7e in init_client_errs ()
    at /install/mysqlconnc/mysql-connector-c-6.0.2/libmysql/errmsg.c:238
No locals.
#8  0x08655fe3 in mysql_server_init (argc=0, argv=0x0, groups=0x0)
    at /install/mysqlconnc/mysql-connector-c-6.0.2/libmysql/libmysql.c:128
        result = 0
#9  0x08651fc0 in mysql_init (mysql=0x0)
    at /install/mysqlconnc/mysql-connector-c-6.0.2/libmysql/client.c:1606

解决方案:

我在创建线程之前调用了 mysql_library_init() ,并在线程终止后调用了 mysql_library_end() 。在每个线程中,我在线程函数的开始处调用 mysql_thread_init() ,并在线程函数的末尾调用 mysql_thread_end() 。这样就解决了崩溃的问题。

最佳答案

更新:

看来你需要调用mysql_library_init()mysql_init() 之前:

You must either call mysql_library_init() prior to spawning any threads, or else use a mutex to protect the call, whether you invoke mysql_library_init() or indirectly through mysql_init(). Do this prior to any other client library call.

关于您原来的问题,libmysqlclient_r.so实际上是libmysql.so的符号链接(symbolic link)。您可以通过从以下行中删除 SHARED 关键字来更改 libmysql/CMakeLists.txt 以生成静态库 (libmysql.a):

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

但是,我建议 (1) 尝试在不使用线程的情况下运行相同的代码,看看问题是否仍然存在,(2) 构建并使用库的调试版本:

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

这样您就可以更详细地调查问题。

关于mysql - 在多线程应用程序中使用 libmysqlclient,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11313686/

相关文章:

javascript - 为什么我的 jQuery Ajax GET 请求没有收到服务器的响应?

c - 从同一表字段调用 C 函数时获取表作为自动参数

c - 在 C 语言中创建测量两点之间距离的程序时遇到问题

c - C 中的嵌套 While 循环

linux - 使用 docker 应用程序在外部硬盘驱动器中创建一个新目录

linux - 通过 cron 执行脚本时使用 Zend Lucene 的 PHP iconv 错误,但不在命令行上

c++ - 当守护进程通过 inetd 运行时,xerces-c 库函数返回 NULL

MySQL - Perl : How to use an array with IN within a select query?(在(@array)中)

php - fatal error : Uncaught exception 'PDOException' with message 'SQLSTATE[42000]:

mysql - 我是否需要在 SUM(col) 使用的列上创建索引?