Windows服务器端编程-第二章 设备IO与线程间通信-10-线程池有多少线程
来源:互联网 发布:安装ubuntu命令行乱码 编辑:程序博客网 时间:2024/06/08 06:00
l 线程池有多少线程
现在是讨论线程池内应该有多少线程的恰当时机。从两个方面考虑。首先,在服务应用程序初始化时,要创建最少的线程集而不必以正常方法创建和销毁。记住,创建和销毁线程会浪费CPU时间,因此进程的线程数量越小越好。其次,线程的数量要有一个最大值,创建过多的线程会浪费系统资源。即使大部部分资源可以被对换出内存,最小化对系统资源的使用以及不浪费页面空间仍然很有优势,如果能够做到的话。
你可能想体会一下不同数量的线程的结果。大多数服务(包括微软的IIS)使用启发式算法来管理它们的线程池。建议你也这么做。例如,可以以下的变量来管理线程池。
LONG g_nThreadsMin; // 线程池内线程的最小数量
LONG g_nThreadsMax; // 线程池内线程的最大数量
LONG g_nThreadsCrnt; //当前线程池内的线程数量
LONG g_nThreadsBusy; // 线程池内正在干活的线程数量
在应用程序初始化时,创建等于g_nThreadsMin的数量的线程,这些线程都执行相同线程池函数。以下伪代码展示了一个线程池函数:
DWORD WINAPI ThreadPoolFunc(PVOID pv) {
// 线程正在进入线程池
InterlockedIncrement(&g_nThreadsCrnt);
InterlockedIncrement(&g_nThreadsBusy);
for (BOOL fStayInPool = TRUE; fStayInPool;) {
// 线程停止执行并等待工作
InterlockedDecrement(&m_nThreadsBusy);
BOOL fOk = GetQueuedCompletionStatus(...);
DWORD dwIOError = GetLastError();
// 线程有工作要做,因此处于忙状态
int nThreadsBusy = InterlockedIncrement(&m_nThreadsBusy);
// 应该加另一个线程到线程池中么?
if (nThreadsBusy == m_nThreadsCrnt) { // 所有的线程都在忙
if (nThreadsBusy < m_nThreadsMax) { // 线程池没有满
if (GetCPUUsage() < 75) { // CPU 使用率小于75%
// 向池中添加线程
CloseHandle(chBEGINTHREADEX(...));
}
}
}
if (!fOk && (dwIOError == WAIT_TIMEOUT)) { // 线程超时
if (!ThreadHasIoPending()) {
// 没有太多的服务要做,因此线程可以结束,因为没有未完成的I/O请求
fStayInPool = FALSE;
}
}
if (fOk || (po != NULL)) {
// 线程被唤醒以进行处理,开始进行处理
...
if (GetCPUUsage() > 90) { // CPU 使用率超过 90%
if (!ThreadHasIoPending()) { // 没有阻塞的I/O请求
if (g_nThreadsCrnt > g_nThreadsMin)) { // 当前线程数量大于最小值
fStayInPool = FALSE; // 从池中删除线程
}
}
}
}
}
// 线程离开线程池
InterlockedDecrement(&g_nThreadsBusy);
InterlockedDecrement(&g_nThreadsCurrent);
return(0);
}
这段伪码展示了使用完成端口时可以有多大的创造性。GetCPUUsage和ThreadHasIoPending函数并不是Windows API。如果想使用它们,必须自己实现。另外,必须保证线程池内至少总是有一个线程,否则客户端将永远被挡在门外。可以上面的伪码为参考,不过特定的服务应用程序如果使用不同的架构可能会有更好的效果。
注意
在本章的前面,小节“取消设备队列中的I/O请求”,曾说过系统会在线程终止时自动取消该线程产生的所有被阻塞的I/O请求。这就是为什么伪码中像ThreadHasIoPending这样函数必需存在。如果线程仍有未完成的I/O请求,不要终止线程。
- Windows服务器端编程-第二章 设备IO与线程间通信-10-线程池有多少线程
- Windows服务器端编程-第二章 设备IO与线程间通信-9-I/O完成端口对线程池的管理
- Windows服务器端编程-第二章 设备IO与线程间通信-6-创建完成端口
- Windows服务器端编程-第二章 设备IO与线程间通信-12-代码清单(完)
- Windows服务器端编程-第二章 设备I/O与线程间通信-1
- Windows服务器端编程-第二章 设备IO与线程通信-5-I/O完成端口
- Windows服务器端编程-第二章 设备IO与线程间通信-7-将设备与完成端口关联
- Windows服务器端编程-第二章 设备IO与线程间通信-2-异步设备I/O操作基础
- Windows服务器端编程-第二章 设备IO与线程间通信-8-围绕I/O完成端口的架构
- Windows服务器端编程-第二章 设备IO与线程间通信-11-模拟已完成的I/O请求
- Windows服务器端编程-第二章 设备IO和线程间通信-3-接收I/O请求的完成通知
- Windows服务器端编程-第二章 设备IO和线程间通信-4-警告式I/O的优缺点
- 《Microsoft Windows 2000 服务器端编程》 -- 第二章 设备I/O和线程间通信
- 线程与线程间通信
- Windows线程间通信
- Windows线程间通信
- IO编程与线程概念
- Windows2000 服务器端应用程序开发设计指南-设备I/O及线程间通讯
- 签劳动合同的六大注意事项
- 使用户能够在USB设备上存储数据、应用软件、个人桌面的软件正在进入企业
- Windows服务器端编程-第二章 设备IO与线程间通信-9-I/O完成端口对线程池的管理
- 使用Handler来增强Web服务的功能
- C++ Templates基础篇
- Windows服务器端编程-第二章 设备IO与线程间通信-10-线程池有多少线程
- 菜鸟蹒跚学ASP-学习语法篇
- 每天学一点flash(4) 数组与xml配合使用
- VC编码规范
- 学习笔记----Tomcat 的WEB 安全域
- 破解网站列表
- Windows服务器端编程-第二章 设备IO与线程间通信-11-模拟已完成的I/O请求
- 【转】java枚举类型入门
- 盛大技术经理金万钠谈:技术高手的十三个原则