MySQL數(shù)據(jù)庫線程緩沖池詳解
MySQL數(shù)據(jù)庫線程緩沖池的相關(guān)知識是本文我們主要要介紹的內(nèi)容,MySQL數(shù)據(jù)庫支持線程緩存,在多線程連接模式下,如果連接斷開后,將這個(gè)線程放入空閑線程緩沖區(qū),在下次有連接到來時(shí),先去緩沖池中查找是否有空閑線程,有則用之,無則創(chuàng)建。啟動(dòng)時(shí)可以設(shè)置線程緩沖池的數(shù)目:Mysqld.exe --thread_cache_size=10。
在一個(gè)連接斷開時(shí),會調(diào)用cache_thread函數(shù),將空閑的線程加入到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);
- }
上面我們的啟動(dòng)參數(shù)設(shè)置線程緩沖區(qū)為10,此時(shí)對應(yīng)代碼里面的thread_cache_size = 10,cached_thread_count記錄
了此刻cache中的空閑線程數(shù)目,只有在cache未滿的情況下,才會將新的空閑線程加入緩沖池中。加入到緩沖區(qū)其實(shí)就是將線
程掛起,pthread_cond_wait函數(shù)便是線程等待函數(shù),在此函數(shù)中,會調(diào)用WaitForMultipleObjects進(jìn)行事件等待。具體源碼
如下:
- 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;
- }
此處是等待時(shí)間,何處進(jìn)行事件通知呢?我們再次來到上篇所提及的為新的連接創(chuàng)建線程的代碼中:
- 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
- ...
- }
關(guān)于MySQL數(shù)據(jù)庫線程緩沖池的相關(guān)知識就介紹到這里了,希望本次的介紹能夠?qū)δ兴斋@!
【編輯推薦】


2009-06-16 09:25:31




