在multithreading应用程序中使用libmysqlclient
我正在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
如果我的应用程序是multithreading的,我可以将我的应用程序与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 , file = 0x65685f65 , 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_init()
之前调用mysql_library_init mysql_init()
:
您必须在产生任何线程之前调用mysql_library_init(),或者使用互斥锁来保护调用,无论是调用mysql_library_init()还是通过mysql_init()间接调用。 在任何其他客户端库调用之前执行此操作。
关于您的原始问题, libmysqlclient_r.so
实际上是libmysqlclient_r.so
的符号链接。 您可以通过从以下行中删除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
这样您可以更详细地调查问题。