MySQL数据库线程缓冲池的相关知识是本文我们主要要介绍的内容,MySQL数据库支持线程缓存,在多线程连接模式下,如果连接断开后,将这个线程放入空闲线程缓冲区,在下次有连接到来时,先去缓冲池中查找是否有空闲线程,有则用之,无则创建。启动时可以设置线程缓冲池的数目:Mysqld.exe –thread_cache_size=10。

在一个连接断开时,会调用cache_thread函数,将空闲的线程加入到cache中,以备后用。源码如下:

    staticboolcache_thread() { safe_mutex_assert_owner(&LOCK_thread_count); if( cached_thread_count<thread_cache_size&& !abort_loop&&!kill_cached_threads) { /*Don'tkillthethread,justputitincacheforreuse*/ DBUG_PRINT("info",("Addingthreadtocache")); 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;//Forstore_globals (void)thd->store_globals(); /* THD::mysys_var::abortisassociatedwithphysicalthreadrather thanwithTHDobject.Soweneedtoresetthisflagbeforeusing thisthreadforhandlingofnewTHDobject/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进行事件等待。具体源码

如下:

    intpthread_cond_timedwait(pthread_cond_t*cond,pthread_mutex_t*mutex, structtimespec*abstime) intresult; longtimeout; unionft64now; if(abstime!=NULL) { GetSystemTimeAsFileTime(&now.ft); /* Calculatetimelefttoabstime -subtractstarttimefromcurrenttime(valuesarein100nsunits) -converttomillisecbydividingwith10000 */ timeout=(long)((abstime->tv.i64-now.i64)/10000); /*Don'tallowthetimeouttobenegative*/ if(timeout<0) timeout=0L; /* Makesurethecalucatedtimeoutdoesnotexceedoriginaltimeout valuewhichcouldcause"waitforever"ifsystemtimechanges */ if(timeout>abstime->max_timeout_msec) timeout=abstime->max_timeout_msec; } else { /*Notimespecified;don'texpire*/ timeout=INFINITE; } /* Blockaccessifpreviousbroadcasthasn'tfinished. Thisisjustforsafetyandshouldnormallynot affectthetotaltimespentinthisfunction. */ 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'rethelastwaitertobenotifiedortostopwaiting,so resetthemanualevent. */ /*Closebroadcastgate*/ ResetEvent(cond->events[BROADCAST]); /*Openblockgate*/ SetEvent(cond->broadcast_block_event); } LeaveCriticalSection(&cond->lock_waiting); EnterCriticalSection(mutex); returnresult==WAIT_TIMEOUT?ETIMEDOUT:0; }

此处是等待时间,何处进行事件通知呢?我们再次来到上篇所提及的为新的连接创建线程的代码中:

    voidcreate_thread_to_handle_connection(THD*thd) { if(cached_thread_count>wake_thread) { /*Getthreadfromcache*/ thread_cache.append(thd); wake_thread++; pthread_cond_signal(&COND_thread_cache); } Else ... }

关于MySQL数据库线程缓冲池的相关知识就介绍到这里了,希望本次的介绍能够对您有所收获!

【编辑推荐】

    如何检查MySQL数据库的主从延时?MySQL数据库时间类型的物理存储Linux cron执行MySQL失败的问题解决方案PHP与MySQL数据库中排序的对比及使用条件详解MySQL性能优化之使用Limit关键字来避免全表扫描