2012-07-03 4 views
1

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()를 호출합니다. 이것은 충돌의 문제를 해결했습니다.

답변

2

업데이트는 :

당신이 mysql_library_init()mysql_init() 전에 호출 할 필요가 보인다 : 당신은 mysql_library_init()를 호출해야 하나

어떤 스레드를 산란, 또는 다른 보호하기 위해 뮤텍스를 사용하기 전에 호출, mysql_library_init() 호출 또는 mysql_init()를 통한 간접 호출. 다른 클라이언트 라이브러리 호출에 앞서이 작업을 수행하십시오.

원래 질문에 대해서는 libmysqlclient_r.so은 실제로 libmysql.so의 심볼릭 링크입니다.스레드를 사용하지 않고 I (1) 동일한 코드를 실행하려고 추천 할 것입니다, 그러나

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

하고 있는지 : 대신 다음 줄에서 SHARED 키워드를 제거하여 정적 라이브러리 (libmysql.a)을 생산하는 libmysql/CMakeLists.txt을 변경할 수 있습니다 문제가 지속됩니다. (2) 라이브러리의 디버그 버전을 빌드하고 사용하십시오.

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

이 방법을 사용하면 문제를 자세히 조사 할 수 있습니다.

+0

답변을 제공해 주셔서 감사합니다. 위 질문에 추가 한 업데이트를 확인하십시오. – geekowl

+0

@geekowl : 제공된 추가 정보를 고려하여 답변을 업데이트했습니다. – vitaut

+0

당신이 옳습니다. 스레드를 만들기 전에 mysql_library_init()을 호출하고 충돌 문제를 해결했습니다. 당신의 소중한 제안에 감사드립니다. 그들은 큰 문제를 해결하는 데 도움이되었습니다. – geekowl

관련 문제