2013-05-22 53 views
1

我在我的應用程序中使用了兩個mysql對象。在退出線程之前,我只需撥打mysql_thread_end一次。是否有任何函數/回調,以便在退出線程之前調用?在退出C++中的線程之前調用mysql_thread_end函數pthread

樣本程序連接

using namespace std; 
class MySql 
{ 
public: 
    MySql() 
    { 
     mysql = mysql_init(NULL); 
    } 
    ~MySql() 
    { 
     if(mysql) 
     { 
      mysql_close(mysql); 
     } 
    // Wrong: this will clear thread specific values twice. it may lead to crash the application. 
     // mysql_thread_end(); 
    } 
    int Connect(const char *host, 
         const char *user, 
         const char *passwd, 
         const char *db, 
         unsigned int port, 
         const char *unix_socket, 
         unsigned long clientflag) 
    { 
     if(!mysql_real_connect(mysql, host,user, 
          passwd, db, port, unix_socket, clientflag)) 
     { 
     return 1; 
     } 
     return 0; 
    } 
    int Execute(const char *query) 
    {  
     int status = mysql_query(mysql, query); 
     return status; 
    } 
private: 
    MYSQL * mysql; 
}; 

void createthreads(); 
static void StartThread(void * Arg); 

int main(int argc, _TCHAR* argv[]) 
{ 
    int i = mysql_library_init(0, NULL, NULL); 
    createthreads();  
    mysql_library_end(); 
    return 0; 
} 

void createthreads() 
{ 
    PRThread *thread; 

    thread = PR_CreateThread(PR_USER_THREAD, StartThread, (void *)NULL, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); 
    //Sleep(2000); 
    PR_JoinThread(thread); 
} 

void StartThread(void * Arg) 
{ 
    MySql mysqlsrc; 
    MySql mysqldest; 

    //Production server 
    if(!mysqlsrc.Connect("localhost","root", "root", NULL, 3306, NULL, 0)) 
    { 
     cout<<"Connection to Src Failed"; 
     return; 
    } 

    //Test Server 
    if(!mysqldest.Connect("localhost","root", "root", NULL, 3306, NULL, 0)) 
    { 
     cout<<"Connection to Destn Failed"; 
     return; 
    } 

    /// Sync databases.  
} 
+0

那麼,爲什麼不把它作爲最後一個語句調用,然後再從鏈接的文檔中提到的'StartThread()'返回呢? – alk

+0

我們應該在關閉mysql連接之後調用mysql_thread_end(mysql_close) – Sandy

+0

它應該在線程工作完成後執行,即執行被調用。你打算怎麼稱呼後者? – alk

回答

0

由於OP狀態的連接已被關閉後的文檔指出它應被稱爲右側前線程結束我會建議國防部StartThreadmysql_thread_end()將被稱爲(線程函數)如下:

void StartThread(void * Arg) 
{ 
    { 
    MySql mysqlsrc; 
    MySql mysqldest; 

    //Production server 
    if(!mysqlsrc.Connect("localhost","root", "root", NULL, 3306, NULL, 0)) 
    { 
     cout<<"Connection to Src Failed"; 
     return; 
    } 

    //Test Server 
    if(!mysqldest.Connect("localhost","root", "root", NULL, 3306, NULL, 0)) 
    { 
     cout<<"Connection to Destn Failed"; 
     return; 
    } 

    /// Sync databases. 
    } /* MySql objects run out of scope, their d`tor will be called, so mysql_close() is called also. */ 

    mysql_thread_end(); 
} 
+0

在我的應用程序中,每個動作都會創建一個新線程,並且它會調用獨立的函數來確定所選動作。問題是我必須在退出線程之前每次調用此函數。我想知道是否有任何函數會在退出線程之前自動調用。 – Sandy

+0

「*我必須在退出線程前每次調用此函數... *」:這正是我的答案所顯示的代碼。 – alk

0

thread-specific data標準並行線程設施允許thread-specific data destructors是REGI因此可能用於implement a sort of "pthread exit hook"

,胡克的話,可以撥打mysql_thread_end(),你的代碼的其餘部分不需要知道的是:

using namespace std; 

// --> XXX WARNING UNTESTED AND ERROR CHECKING OMITTED XXX <---- 

namespace { 
    pthread_key_t key; 
    pthread_key_once key_once = PTHREAD_ONCE_INIT; 

    void cleanup(void *dummy) // called at thread termination 
    { 
     mysql_thread_end(); 
    } 
    void key_init()   // called pthread_once and only once 
    { 
     (void)pthread_key_create(&key, mycleanup); 
    } 
    void workaround_bz66740() // call after you know mysql_thread_init has been called 
    { 
     (void)pthread_once(&key_once, key_init); 
     (void)pthread_setspecific(key, (const void *)1); 
    } 
} 

class MySql 
{ 
public: 
    MySql() 
    { 
     mysql = mysql_init(NULL); 
     workaround_bz66740(); 
    } 
    .... 

旁註:你需要明確的清理MySQL的資源其實是累贅並且很遺憾,正如在MySQL change request #66740中所闡明的那樣。