Linux 플랫폼에서 C 응용 프로그램을 빌드 중입니다. 데이터베이스에 인터페이스하기 위해 libmysqlclient를 사용해야합니다.다중 스레드 응용 프로그램에서 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 내 응용 프로그램을 링크 할 수 있습니다? mysake 문서 (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);
mysql 클라이언트 라이브러리에 정적으로 링크하고자하므로 libmysqlclient_r.so를 사용하지 않습니다. 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()를 호출합니다. 이것은 충돌의 문제를 해결했습니다.
답변을 제공해 주셔서 감사합니다. 위 질문에 추가 한 업데이트를 확인하십시오. – geekowl
@geekowl : 제공된 추가 정보를 고려하여 답변을 업데이트했습니다. – vitaut
당신이 옳습니다. 스레드를 만들기 전에 mysql_library_init()을 호출하고 충돌 문제를 해결했습니다. 당신의 소중한 제안에 감사드립니다. 그들은 큰 문제를 해결하는 데 도움이되었습니다. – geekowl