목차
one-connection-per-thread
线程池与epoll
线程池函数调用关系
one-connection-per-thread函数调用关系
데이터 베이스 MySQL 튜토리얼 MySQL详解(8)----------MySQL线程池总结(二)_MySQL

MySQL详解(8)----------MySQL线程池总结(二)_MySQL

Jun 01, 2016 pm 12:59 PM

这篇文章是对上篇文章的一个补充,主要围绕以下两点展开,one-connection-per-thread的实现方式以及线程池中epoll的使用。

one-connection-per-thread

根据scheduler_functions的模板,我们也可以列出one-connection-per-thread方式的几个关键函数。

static scheduler_functions con_per_functions=

{ max_connection+1, // max_threads

NULL,

NULL,

NULL, // init

Init_new_connection_handler_thread, // init_new_connection_thread

create_thread_to_handle_connection, // add_connection

NULL, // thd_wait_begin

NULL, // thd_wait_end

NULL, // post_kill_notification

one_thread_per_connection_end, // end_thread

NULL // end

};
로그인 후 복사

1.init_new_connection_handler_thread

这个接口比较简单,主要是调用pthread_detach,将线程设置为detach状态,线程结束后自动释放所有资源。

2.create_thread_to_handle_connection

这个接口是处理新连接的接口,对于线程池而言,会从thread_id%group_size对应的group中获取一个线程来处理,而one-connection-per-thread方式则会判断是否有thread_cache可以使用,如果没有则新建线程来处理。具体逻辑如下:

(1).判断缓存的线程数是否使用完(比较blocked_pthread_count 和wake_pthread大小)

(2).若还有缓存线程,将thd加入waiting_thd_list的队列,唤醒一个等待COND_thread_cache的线程

(3).若没有,创建一个新的线程处理,线程的入口函数是do_handle_one_connection

(4).调用add_global_thread加入thd数组。

3.do_handle_one_connection

这个接口被create_thread_to_handle_connection调用,处理请求的主要实现接口。

(1).循环调用do_command,从socket中读取网络包,并且解析执行;

(2). 当远程客户端发送关闭连接COMMAND(比如COM_QUIT,COM_SHUTDOWN)时,退出循环

(3).调用close_connection关闭连接(thd->disconnect());

(4).调用one_thread_per_connection_end函数,确认是否可以复用线程

(5).根据返回结果,确定退出工作线程还是继续循环执行命令。

4.one_thread_per_connection_end

判断是否可以复用线程(thread_cache)的主要函数,逻辑如下:

(1).调用remove_global_thread,移除线程对应的thd实例

(2).调用block_until_new_connection判断是否可以重用thread

(3).判断缓存的线程是否超过阀值,若没有,则blocked_pthread_count++;

(4).阻塞等待条件变量COND_thread_cache

(5).被唤醒后,表示有新的thd需要重用线程,将thd从waiting_thd_list中移除,使用thd初始化线程的thd->thread_stack

(6).调用add_global_thread加入thd数组。

(7).如果可以重用,返回false,否则返回ture

线程池与epoll

在引入线程池之前,server层只有一个监听线程,负责监听mysql端口和本地unixsocket的请求,对于每个新的连接,都会分配一个独立线程来处理,因此监听线程的任务比较轻松,mysql通过poll或select方式来实现IO的多路复用。引入线程池后,除了server层的监听线程,每个group都有一个监听线程负责监听group内的所有连接socket的连接请求,工作线程不负责监听,只处理请求。对于overscribe为1000的线程池设置,每个监听线程需要监听1000个socket的请求,监听线程采用epoll方式来实现监听。

Select,poll,epoll都是IO多路复用机制,IO多路复用通过一种机制,可以监听多个fd(描述符),比如socket,一旦某个fd就绪(读就绪或写就绪),能够通知程序进行相应的读写操作。epoll相对于select和poll有了很大的改进,首先epoll通过epoll_ctl函数注册,注册时,将所有fd拷贝进内核,只拷贝一次不需要重复拷贝,而每次调用poll或select时,都需要将fd集合从用户空间拷贝到内核空间(epoll通过epoll_wait进行等待);其次,epoll为每个描述符指定了一个回调函数,当设备就绪时,唤醒等待者,通过回调函数将描述符加入到就绪链表,无需像select,poll方式采用轮询方式;最后select默认只支持1024个fd,epoll则没有限制,具体数字可以参考cat /proc/sys/fs/file-max的设置。epoll贯穿在线程池使用的过程中,下面我就epoll的创建,使用和销毁生命周期来描述epoll在线程中是如何使用的。

线程池初始化,epoll通过epoll_create函数创建epoll文件描述符,实现函数是thread_group_init;端口监听线程监听到请求后,创建socket,并创建THD和connection对象,放在对应的group队列中;工作线程获取该connection对象时,若还未登录,则进行登录验证若socket还未注册到epoll,则调用epoll_ctl进行注册,注册方式是EPOLL_CTL_ADD,并将connection对象放入epoll_event结构体中若是老连接的请求,仍然需要调用epoll_ctl注册,注册方式是EPOLL_CTL_MODgroup内的监听线程调用epoll_wait来监听注册的fd,epoll是一种同步IO方式,所以会进行等待请求到来时,获取epoll_event结构体中的connection,放入到group中的队列线程池销毁时,调用thread_group_close将epoll关闭。

备注:

1.注册在epoll的fd,若请求就绪,则将对应的event放入到events数组,并将该fd的事务类型清空,因此对于老的连接请求,依然需要调用epoll_ctl(pollfd, EPOLL_CTL_MOD, fd, &ev)来注册。

线程池函数调用关系

(1)创建epoll

tp_init->thread_group_init->tp_set_threadpool_size->io_poll_create->epoll_create

(2)关闭epoll

tp_end->thread_group_close->thread_group_destroy->close(pollfd)

(3)关联socket描述符

handle_event->start_io->io_poll_associate_fd->io_poll_start_read->epoll_ctl

(4)处理连接请求

handle_event->threadpool_process_request->do_command->dispatch_command->mysql_parse->mysql_execute_command

(5)工作线程空闲时

worker_main->get_event->pthread_cond_timedwait

等待thread_pool_idle_timeout后,退出。

(6)监听epoll

worker_main->get_event->listener->io_poll_wait->epoll_wait

(7)端口监听线程

main->mysqld_main->handle_connections_sockets->poll

one-connection-per-thread函数调用关系

(1) 工作线程等待请求

handle_one_connection->do_handle_one_connection->do_command->

my_net_read->net_read_packet->net_read_packet_header->net_read_raw_loop->

vio_read->vio_socket_io_wait->vio_io_wait->poll

备注:与线程池的工作线程有监听线程帮助其监听请求不同,one-connection-per-thread方式的工作线程在空闲时,会调用poll阻塞等待网络包过来;

而线程池的工作线程只需要专心处理请求即可,所以使用也更充分。

(2)端口监听线程

与线程池的(7)相同

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
2 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
2 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
2 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

8코어 16쓰레드란 무엇을 의미하나요? 8코어 16쓰레드란 무엇을 의미하나요? Feb 02, 2023 am 11:26 AM

8코어는 CPU에 8개의 물리적 코어가 있다는 의미이고, 16스레드는 CPU가 동시에 작업을 처리하는 최대 16개의 스레드를 가질 수 있다는 의미입니다. 코어와 스레드의 수는 컴퓨터 CPU의 중요한 성능 지표입니다. CPU의 코어 수가 많을수록 처리 속도가 높을수록 여러 프로그램을 동시에 실행하는 데 도움이 됩니다. 왜냐하면 스레드 수는 특정 순간에 CPU가 동시에 실행할 수 있는 횟수와 동일하기 때문입니다. 멀티스레딩은 광범위한 문제, 비순차적 수퍼스칼라 처리를 극대화하고, 프로세서 컴퓨팅 구성 요소의 활용도를 향상시키며, 데이터 상관 관계 또는 캐시 누락으로 인한 메모리 액세스 지연을 완화할 수 있습니다.

C++ 동시 프로그래밍: 스레드 고갈과 우선순위 반전을 방지하는 방법은 무엇입니까? C++ 동시 프로그래밍: 스레드 고갈과 우선순위 반전을 방지하는 방법은 무엇입니까? May 06, 2024 pm 05:27 PM

스레드 부족을 방지하려면 공정한 잠금을 사용하여 리소스를 공정하게 할당하거나 스레드 우선순위를 설정할 수 있습니다. 우선순위 역전 문제를 해결하려면 리소스를 보유한 스레드의 우선순위를 일시적으로 높이는 우선순위 상속을 사용하거나 리소스가 필요한 스레드의 우선순위를 높이는 잠금 승격을 사용할 수 있습니다.

C++ 동시 프로그래밍: 스레드 종료 및 취소를 수행하는 방법은 무엇입니까? C++ 동시 프로그래밍: 스레드 종료 및 취소를 수행하는 방법은 무엇입니까? May 06, 2024 pm 02:12 PM

C++의 스레드 종료 및 취소 메커니즘은 다음과 같습니다. 스레드 종료: std::thread::join()은 대상 스레드가 실행을 완료할 때까지 현재 스레드를 차단합니다. std::thread::detach()는 스레드 관리에서 대상 스레드를 분리합니다. 스레드 취소: std::thread::request_termination()은 대상 스레드에 실행을 종료하도록 요청합니다. std::thread::get_id()는 대상 스레드 ID를 획득하고 std::terminate()와 함께 사용하여 대상을 즉시 종료할 수 있습니다. 실. 실제 전투에서 request_termination()은 스레드가 종료 시점을 결정하도록 허용하고, Join()은 이를 메인 라인에서 보장합니다.

프로그램이 실행될 때 명령 흐름의 가장 작은 단위는 무엇입니까? 프로그램이 실행될 때 명령 흐름의 가장 작은 단위는 무엇입니까? Aug 23, 2022 pm 02:16 PM

"스레드"는 프로그램이 실행될 때 명령 흐름의 가장 작은 단위입니다. 프로세스는 특정 독립적인 기능을 가진 프로그램을 말하며, 스레드는 프로세스의 일부로 명령 흐름의 실행 상태를 설명합니다. 스레드는 프로세스에서 명령 실행 흐름의 가장 작은 단위이며 기본 단위입니다. CPU 스케줄링의 스레드는 작업(프로그램 세그먼트)의 실행 프로세스입니다. 스레드는 메모리 공간을 차지하지 않으며 프로세스의 메모리 공간에 포함됩니다. 동일한 프로세스 내에서 여러 스레드가 프로세스의 리소스를 공유합니다. 프로세스에는 하나 이상의 스레드가 있습니다.

Java 오류: JavaFX 스레드 중단 오류, 처리 및 방지 방법 Java 오류: JavaFX 스레드 중단 오류, 처리 및 방지 방법 Jun 24, 2023 pm 05:52 PM

JavaFX 애플리케이션을 개발하는 동안 JavaFX 스레드 중단 오류가 자주 발생합니다. 이러한 오류는 심각도가 다양하며 프로그램 안정성과 성능에 부정적인 영향을 미칠 수 있습니다. 프로그램의 정상적인 작동을 보장하려면 JavaFX 스레드 중단 오류의 원인과 해결 방법, 그리고 이 오류가 발생하지 않도록 방지하는 방법을 이해해야 합니다. 1. JavaFX 스레드 중단 오류의 원인 JavaFX는 프로그램이 백그라운드 스레드에서 오랫동안 실행될 수 있도록 하는 다중 스레드 UI 응용 프로그램 프레임워크입니다.

Go 언어의 스레드와 프로세스의 차이점 분석 Go 언어의 스레드와 프로세스의 차이점 분석 Apr 03, 2024 pm 01:39 PM

Go 언어의 프로세스 및 스레드: 프로세스: 자체 리소스와 주소 공간을 가지고 독립적으로 실행되는 프로그램 인스턴스입니다. 스레드: 프로세스 리소스와 주소 공간을 공유하는 프로세스 내의 실행 단위입니다. 특징: 프로세스: 높은 오버헤드, 우수한 격리, 독립적인 스케줄링. 스레드: 낮은 오버헤드, 공유 리소스, 내부 스케줄링. 실제 사례: 프로세스: 장기 실행 작업 격리. 스레드: 대량의 데이터를 동시에 처리합니다.

Go 언어에서 코루틴과 스레드의 차이점은 무엇입니까? Go 언어에서 코루틴과 스레드의 차이점은 무엇입니까? Feb 02, 2023 pm 06:10 PM

차이점: 1. 스레드는 여러 개의 코루틴을 가질 수 있으며 프로세스는 여러 개의 코루틴을 단독으로 가질 수도 있습니다. 2. 스레드는 동기화 메커니즘인 반면 코루틴은 비동기식입니다. 3. 코루틴은 마지막 호출 상태를 유지할 수 있으며 스레드는 작동하지 않습니다. ; 4. 스레드는 선점형이지만 코루틴은 비선점형입니다. 5. 스레드는 CPU 리소스를 분할하고 코루틴은 호스트하고 실행하는 데 필요한 코드 프로세스입니다.

Microsoft는 Windows의 Outlook 클래식 앱에 AI 기반 Copilot을 도입할 계획입니다. Microsoft는 Windows의 Outlook 클래식 앱에 AI 기반 Copilot을 도입할 계획입니다. Oct 19, 2023 pm 11:13 PM

Microsoft는 강력한 AI 기반 Copilot 도구를 새 앱의 독점 기능으로 유지하지 않을 것으로 보입니다. 이제 회사는 Windows의 Outlook 클래식 앱에 Copilot을 도입할 계획을 발표했습니다. 365 로드맵 웹사이트에 게시된 대로 미리 보기는 내년 3월에 시작되며 3월까지 현재 채널의 데스크톱에서 전 세계적으로 출시될 예정입니다. Copilot은 LLM(대형 언어 모델)을 사용하여 이메일 작성, 문서 요약, 언어 번역 등의 작업을 사용자에게 지원하는 생산성 도구입니다. 주요 기능 중 하나는 이메일을 요약하는 기능입니다.

See all articles