大家都知道使用线程实现异步函数操作,尤其是顺序执行需要消耗大量时间的时候;而线程池是为了解决频繁启动和撤销线程所带来的系统开销以及引发的一系列内存出错的问题(当时频繁启用程经常遇到的问题);然后就有了线程池技术;就是在启动多线程的时候首先建立一个线程池,然后每次请求放入线程池的请求队列中;同时每次线程池里面的线程执行完之后,并不退出线程;而是保留在线程池中,等待下一次数据请求。这是我对线程池的理解。
接着我想讲讲我的应用需求:我有一个接收数据的服务器,服务器不定时的接收数据,并且每接收一个数据都被放入数据库;看似很简单;以前的解决方案:如果每次一个数据同时的插库操作启动一个线程,用于数据包的解析和插库操作;这样有可能频繁启动线程和退出线程造成系统开销很大;同时也可能出现频繁创建线程造成的内存泄露的问题;接着就想了一个平滑的方案,就是当接收到数据时进行一个缓存,当接收的数据达到一定数据量时才对这些数据进行插库操作;这样可能起到一定的好处,但是由于数据量的频率的不确定,同时缓冲区的大小不好设定;而且当数据量极大的时候,线程启动也会带来错误;同时数据的实时性不强;
现在我就想要使用线程池的技术,网上有很多自己写的线程池;但是为了简便我使用了系统API的进行线程池的管理,具体资料就不多说 这挂一个网址:http://www.cppblog.com/tx7do/archive/2006/04/14/5576.aspx 以后可以使用;只是想说明一下 QueueUserWorkItem函数调用与异步函数 DWORD API functionName()
之间的调用关系:第一次使用QueueUserWorkItem()函数时创建线程池,然后以后每次把线程请求往线程池里面添加请求;过程很简单;但是有个问题:当QueueUserWorkItem()函数执行后直接返回;可能线程函数都没有执行完毕就返回;整个程序也退出了!解决方案:QueueUserWorkItem()第三个参数用WT_EXECUTELONGFUNCTION;表示线程需要长时间完成;当有新需求时,创建新线程;同时在调用完QueueUserWorkItem()添加一个Sleep(1);这样能够保证程序能够正常完成;这个机制是什么?我现在还没有搞清楚,知道的朋友可以给点解释!谢谢了~!
注意头文件:#include<windows.h>
下面贴出简单的线程池代码:程序目的是多线程打印数据,同时里面有的疑问请网友解释:
// first.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
DWORD WINAPI ThreadFuc(PVOID PvContext);
void TestWorkItem();
int _tmain(int argc, _TCHAR* argv[])
{
TestWorkItem();
return 0;
}
DWORD WINAPI ThreadFuc(PVOID PvContext)
{
//Sleep(1000);
int num=(int)PvContext;
printf("%d\n",num);
return 1;
}
void TestWorkItem()
{
for(int i=0;i<10;i++)
{
QueueUserWorkItem(ThreadFuc,(PVOID)i,WT_EXECUTELONGFUNCTION);
Sleep(1);//如果不写这句,可能会造成线程不运行直接退出程序的结果;能把1——10的数据打印完!
不写Sleep()的结果
不能把1——10的数据打印完;
}
}