MySQL資料庫線程緩衝池的相關知識是本文我們主要要介紹的內容,MySQL資料庫支援線程緩衝,在多線程串連模式下,如果串連斷開後,將這個線 程放入空閑線程緩衝區,在下次有串連到來時,先去緩衝池中尋找是否有空閑線程,有則用之,無則建立。啟動時可以設定線程緩衝池的數 目:Mysqld.exe --thread_cache_size=10。
在一個串連斷開時,會調用cache_thread函數,將閒置線程加入到cache中,以備後用。源碼如下:
以下是程式碼片段: static bool cache_thread() { safe_mutex_assert_owner(&LOCK_thread_count); if ( cached_thread_count < thread_cache_size && ! abort_loop && !kill_cached_threads) { /* Don't kill the thread, just put it in cache for reuse */ DBUG_PRINT("info", ("Adding thread to cache")); cached_thread_count++; while (!abort_loop && ! wake_thread && ! kill_cached_threads) (void) pthread_cond_wait(&COND_thread_cache, &LOCK_thread_count); cached_thread_count--; if (kill_cached_threads) pthread_cond_signal(&COND_flush_thread_cache); if (wake_thread) { THD *thd; wake_thread--; thd= thread_cache.get(); thd->thread_stack= (char*) &thd; // For store_globals (void) thd->store_globals(); /* THD::mysys_var::abort is associated with physical thread rather than with THD object. So we need to reset this flag before using this thread for handling of new THD object/connection. */ thd->mysys_var->abort= 0; thd->thr_create_utime= my_micro_time(); threads.append(thd); return(1); } } return(0); } |
上面我們的啟動參數設定線程緩衝區為10,此時對應代碼裡面的thread_cache_size = 10,cached_thread_count記錄
了此刻cache中的空閑線程數目,只有在cache未滿的情況下,才會將新的空閑線程加入緩衝池中。加入到緩衝區其實就是將線
程掛起,pthread_cond_wait函數便是線程等待函數,在此函數中,會調用WaitForMultipleObjects進行事件等待。具體源碼
如下:
以下是程式碼片段: int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, struct timespec *abstime) int result; long timeout; union ft64 now; if( abstime != NULL ) { GetSystemTimeAsFileTime(&now.ft); /* Calculate time left to abstime - subtract start time from current time(values are in 100ns units) - convert to millisec by dividing with 10000 */ timeout= (long)((abstime->tv.i64 - now.i64) / 10000); /* Don't allow the timeout to be negative */ if (timeout < 0) timeout= 0L; /* Make sure the calucated timeout does not exceed original timeout value which could cause "wait for ever" if system time changes */ if (timeout > abstime->max_timeout_msec) timeout= abstime->max_timeout_msec; } else { /* No time specified; don't expire */ timeout= INFINITE; } /* Block access if previous broadcast hasn't finished. This is just for safety and should normally not affect the total time spent in this function. */ WaitForSingleObject(cond->broadcast_block_event, INFINITE); EnterCriticalSection(&cond->lock_waiting); cond->waiting++; LeaveCriticalSection(&cond->lock_waiting); LeaveCriticalSection(mutex); result= WaitForMultipleObjects(2, cond->events, FALSE, timeout); EnterCriticalSection(&cond->lock_waiting); cond->waiting--; if (cond->waiting == 0) { /* We're the last waiter to be notified or to stop waiting, so reset the manual event. */ /* Close broadcast gate */ ResetEvent(cond->events[BROADCAST]); /* Open block gate */ SetEvent(cond->broadcast_block_event); } LeaveCriticalSection(&cond->lock_waiting); EnterCriticalSection(mutex); return result == WAIT_TIMEOUT ? ETIMEDOUT : 0; } |
此處是等待時間,何處進行事件通知呢?我們再次來到上篇所提及的為新的串連建立線程的代碼中:
以下是程式碼片段: void create_thread_to_handle_connection(THD *thd) { if (cached_thread_count > wake_thread) { /* Get thread from cache */ thread_cache.append(thd); wake_thread++; pthread_cond_signal(&COND_thread_cache); } Else ... } |
關於MySQL資料庫線程緩衝池的相關知識就介紹到這裡了,希望本次的介紹能夠對您有所收穫!