惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

K
Kaspersky official blog
Martin Fowler
Martin Fowler
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
V
Visual Studio Blog
博客园_首页
Engineering at Meta
Engineering at Meta
The Cloudflare Blog
MongoDB | Blog
MongoDB | Blog
Blog — PlanetScale
Blog — PlanetScale
T
The Blog of Author Tim Ferriss
雷峰网
雷峰网
D
Docker
博客园 - 司徒正美
S
SegmentFault 最新的问题
M
MIT News - Artificial intelligence
博客园 - 叶小钗
博客园 - 三生石上(FineUI控件)
U
Unit 42
J
Java Code Geeks
A
About on SuperTechFans
N
Netflix TechBlog - Medium
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
S
Security Affairs
I
Intezer
Cisco Talos Blog
Cisco Talos Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
B
Blog RSS Feed
P
Privacy & Cybersecurity Law Blog
T
Tenable Blog
T
Threatpost
H
Hacker News: Front Page
G
Google Developers Blog
博客园 - 【当耐特】
Hugging Face - Blog
Hugging Face - Blog
Apple Machine Learning Research
Apple Machine Learning Research
L
Lohrmann on Cybersecurity
大猫的无限游戏
大猫的无限游戏
Google DeepMind News
Google DeepMind News
A
Arctic Wolf
S
Secure Thoughts
GbyAI
GbyAI
NISL@THU
NISL@THU
S
Security @ Cisco Blogs
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Webroot Blog
Webroot Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
O
OpenAI News
Spread Privacy
Spread Privacy
Application and Cybersecurity Blog
Application and Cybersecurity Blog

博客园 - 悠然小调

nothing.... Ogre中在SceneNode节点旁显示二维字的代码 博文阅读密码验证 - 博客园 最简单的智能指针原理 模板的特化 计算基类虚表指针在派生类中的偏移量 写一个内存拷贝函数 [转]来自 COM 经验的八个教训 COM本质论学习笔记(一)IDL winsock中select的作用 windows核心编程学习笔记(八)结构化异常处理(Structured Exception Handling) [转]亲密接触VC6.0编译器 windows核心编程学习笔记(七)DLL Injection and API Hooking windows核心编程学习笔记(五.续)堆 windows核心编程学习笔记(五)内存映射文件 windows核心编程学习笔记(四)windows内存结构/虚拟内存/线程的堆栈 windows核心编程学习笔记(二)Wait For Kernel Object(s) windows核心编程学习笔记(一)使用Critical Section [转]筛选法求素数
windows核心编程学习笔记(三)线程池(Thread Pooling)
悠然小调 · 2008-03-05 · via 博客园 - 悠然小调

1.为什么使用线程池
      假使你设计了一个服务器程序,有监听线程不断的监听是否有从客户端发来的新登陆请求,如果收到新的请求,那么就新创建一个线程,做一系列针对该客户端的工作,而监听线程得以继续执行,以处理下一个登陆请求。新建的线程处理过登陆之后,很可能就没有其他任务了,因此该线程退出了。
      这里涉及到了线程的创建和销毁,如果在同一时刻收到了50000个登录请求,那就要循环创建50000个线程分别处理,可能当你创建到第500线程时,第一个线程已经退出了。此时频繁的创建和销毁线程所消耗的资源可能超出了线程本身执行正常任务所消耗的资源,这对于效率要求很高的应用是不合适的。
      此时可以考虑用线程池。

2.自己实现线程池
   
如果要自己实现线程池,简单的做法是首先要创建一个信标(semaphore)对象hSemaphore,并初始化可以容纳最多的作业数max,当前资源数为0。然后创建一定数量的工作线程(WorkThread),比如10个线程,这些线程都在循环中WaitForSingleObject(hSemaphore)。由于一开始信标的当前资源数是0,所以信标是unsigned,那么所有线程都处于等待状态。另创建一个任务队列(queue)以及一个工作项目添加函数(例如叫做AddWork(pfnWorkfun, pParam);),每当有新的任务要添加,都执行AddWork,在AddWork内部将pfnWorkfun和pParam配对的加入到任务队列的尾部(例如可以创建一个结构体等等),并调用ReleaseSemaphore使当前资源数增加1。当信标的当前资源数大于1的时候,会发出信号,所有等待的工作线程之一会获得执行。该工作线程pop出队列的第一项,然后在内部调用你的pfnWorkfun来完成具体的操作,最后对信标当前资源数量减1。直到信标当前资源数为0为止。
    上述实现只是简单介绍了流程,完全没有考虑线程的同步,以及动态增减待命工作线程等问题,具体实现时要注意。

3.使用系统提供的线程池
    系统提供了一个非常简单的使用线程池的方法,只需要调用一个函数即可,此函数就是QueueUserWorkItem
    调用该函数并传入例如(2)中所指定的pfnWorkfun以及pParam,系统便自动将此配对工作加入到线程池的工作队列中排队,当系统的线程池中有空闲的线程时就依次取出WorkItem并加以执行。
    这就是所谓的异步执行函数(Call Functions Asynchronously)。

4.当单一内核对象已通知时执行函数(Call Functions When Single Kernel Objects Become Signaled)
    和(3)类似,只不过不是手动添加pfnWorkfun和pParam了,而是注册一个内核对象hObject,并关联对应的pfnWorkfun和pParam。当该对象为signed时,自动添加该对工作到系统的线程池里,从而使得像工作可以执行。

5.当异步I/O完成请求时执行函数(Call Functions When Asynchronous I/O Requests Complete)