时间:2021-07-01 10:21:17 帮助过:50人阅读
MySQL数据库线程缓冲池的相关知识是本文我们主要要介绍的内容,MySQL数据库支持线程缓存,在多线程连接模式下,如果连接断开后,将这个线 程放入空闲线程缓冲区,在下次有连接到来时,先去缓冲池中查找是否有空闲线程,有则用之,无则创建。启动时可以设置线
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数据库线程缓冲池的相关知识就介绍到这里了,希望本次的介绍能够对您有所收获!