MySQL创建线程的方法
MySQL数据库创建线程的相关操作是本文我们主要要介绍的内容,MySQL数据库中,为了提高系统效率,减少频繁创建线程和中止线程的系统消耗,MySQL使用了线程缓冲区的概念,即如果一个连接断开,则并不销毁承载其的线程,而是将此线程放入线程缓冲区,并处于挂起状态,当下一个新的Connection到来时,首先去线程缓冲区去查找是否有空闲的线程,如果有,则使用之,如果没有则新建线程。
1.线程创建函数
大家知道,Mysql现在是插件式的存储引擎,只要实现规定的接口,就可实现自己的存储引擎。故Mysql的线程创建除了出现在主服务器框架外,存储引擎也可能会进行线程的创建。通过设置断点,在我调试的版本中,发现了两个创建线程的函数。
pthread_create:Mysql自用的创建线程函数
os_thread_create:存储引擎innobase的创建线程的函数
os_thread_create是存储引擎innobase的线程函数,先搁浅不研究了,重点看下pthread_create,首先看下其源码。
int pthread_create(pthread_t *thread_id, pthread_attr_t *attr, pthread_handler func, void *param) { HANDLE hThread; struct pthread_map *map; DBUG_ENTER("pthread_create"); if (!(map=malloc(sizeof(*map)))) DBUG_RETURN(-1); map->funcfunc=func; map->paramparam=param; pthread_mutex_lock(&THR_LOCK_thread); #ifdef __BORLANDC__ hThread=(HANDLE)_beginthread((void(_USERENTRY *)(void *)) pthread_start, attr->dwStackSize ? attr->dwStackSize : 65535, (void*) map); #else hThread=(HANDLE)_beginthread((void( __cdecl *)(void *)) pthread_start, attr->dwStackSize ? attr->dwStackSize : 65535, (void*) map); #endif DBUG_PRINT("info", ("hThread=%lu",(long) hThread)); *thread_id=map->pthreadself=hThread; pthread_mutex_unlock(&THR_LOCK_thread); if (hThread == (HANDLE) -1) { int error=errno; DBUG_PRINT("error", ("Can't create thread to handle request (error %d)",error)); DBUG_RETURN(error ? error : -1); } VOID(SetThreadPriority(hThread, attr->priority)) ; DBUG_RETURN(0); } 上面代码首先构造了一个map结构体,成员分别是函数地址和传入参数。然后调用操作系统的接口,_beginthread,但是执行函数并不是传入的函数——func,而是pthread_start,参数为map。继续跟踪pthread_start。
pthread_handler_t pthread_start(void *param) { pthread_handler func=((struct pthread_map *) param)->func void *func_param=((struct pthread_map *) param)->param; my_thread_init(); /* Will always succeed in windows */ pthread_mutex_lock(&THR_LOCK_thread); /* Wait for beginthread to return */ win_pthread_self=((struct pthread_map *) param)->pthreadself; pthread_mutex_unlock(&THR_LOCK_thread); free((char*) param); /* Free param from create */ pthread_exit((void*) (*func)(func_param)); return 0; /* Safety */ } 可以看出,pthread_start中调用了map的func元素,作为真正执行的函数体。OK,创建线程的函数跟踪到此!
2.服务器启动时创建了哪些函数?
通过在两个创建线程的地方设置断点,总结了下,在服务器启动时,创建了如下的线程。
pthread_create创建的线程:
创建线程函数 线程执行函数
create_shutdown_thread
handle_shutdown
start_handle_manager
handle_manager
handle_connections_methods
handle_connections_sockets
innobase的os_thread_create创建的线程:
创建线程函数 线程执行函数
innobase_start_or_create_for_mysql
io_handler_thread(4个)
recv_recovery_from_checkpoint_finish
trx_rollback_or_clean_all_without_sess
innobase_start_or_create_for_mysql
srv_lock_timeout_thread
srv_error_monitor_thread
srv_monitor_thread
srv_master_thread
还可以在调试过程中,通过暂停来看此时服务器中的线程,如下图:
关键字:MySQL、创建线程、方法
新文章:
- CentOS7下图形配置网络的方法
- CentOS 7如何添加删除用户
- 如何解决centos7双系统后丢失windows启动项
- CentOS单网卡如何批量添加不同IP段
- CentOS下iconv命令的介绍
- Centos7 SSH密钥登陆及密码密钥双重验证详解
- CentOS 7.1添加删除用户的方法
- CentOS查找/扫描局域网打印机IP讲解
- CentOS7使用hostapd实现无AP模式的详解
- su命令不能切换root的解决方法
- 解决VMware下CentOS7网络重启出错
- 解决Centos7双系统后丢失windows启动项
- CentOS下如何避免文件覆盖
- CentOS7和CentOS6系统有什么不同呢
- Centos 6.6默认iptable规则详解