MySQL数据库线程缓冲池详解

如题所述

第1个回答  2022-09-26

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

  在一个连接断开时 会调用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= ; thd >thr_create_utime= my_micro_time(); threads append(thd); return( ); } } return( ); }

  上面我们的启动参数设置线程缓冲区为 此时对应代码里面的thread_cache_size = 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 ft now; if( abstime != NULL ) { GetSystemTimeAsFileTime(&now ft); /* Calculate time left to abstime subtract start time from current time(values are in ns units) convert to millisec by dividing with */ timeout= (long)((abstime >tv i now i ) / ); /* Don t allow the timeout to be negative */ if (timeout < ) timeout= L; /* 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( cond >events FALSE timeout); EnterCriticalSection(&cond >lock_waiting); cond >waiting ; if (cond >waiting == ) { /* 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 : ; }

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

以下是代码片段 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 }   lishixinzhi/Article/program/MySQL/201311/29579