我一直在想,是要先说win32多线程呢还是C++多线程,想了想,我觉得我们还是先来说说win32多线程吧,因为说到C++的多线程,很多人都认为是一个笑话,在线程面前,随便一个脚步语言都比C++要好实现得多,但是笑话总归是笑话,C++一直没有将线程纳入标准,但是这不影响我们用C++去写多线程,因为每个平台都有相关的平台函数。由于我个人的原因,所以对于linux又或者unix一点都不熟悉,所以只能和大家谈谈win32多线程的一些知识。
我们知道春运的时候火车票都卖得很紧张,如果说每天火车站发放10000张票,但是我们都知道,火车站通常都开有不少窗口,每个窗口都在销售着这1000万张票,卖一张少一张……现在我们来模拟火车站的售票系统,假设有4个窗口,那就相当于我们开了四条线程。
关于线程的概念,我这里不想多说了,如果大家真心想要弄清楚线程是个啥玩意的话,我的推荐是《windows核心编程》和《win32多线程程序设计》这两本书,当然如果大家没这闲工夫的话,那么跟着我的脚步走一样可以学会开线程。
要创建一条线程,我们首先得认识一个函数:
---------------------------------------------
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAtributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAdress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId);
----------------------------------------------
lpThreadAttributes:
描述施行于这一新线程的security属性。NULL表示使用缺省值,此参数在Windows 95 中被忽略,所以现在我们可以不用理他。
dwStackSize:
新线程拥有自己的堆栈。0表示使用缺省大小:1M。
lpStartAddress:
新线程将开始的起始地址,这是一个函数指针。
lpParameter:
此值将被传送到上述所指定之新线程函数去,作为参数。
dwCreationFlags:
允许你产生一个暂时挂起的线程。默认情况是“立即开始执行”。
lpThreadId:
新线程的ID 会被传回到这里。
这里我们接触了一个新类型:HANDLE,这个类型在开发平台相关系统时会大量的碰到,这里我们可以不用太刻意深究,大家只需要知道这叫做句柄就好,按我目前的理解,可以当他理解为C/C++中指针。
如果上面的CreateThread函数成功,那么将会返回一个handle,代表着一个新的线程,否则返回FALSE,这时我们可以条用GetLastErro()函数来获取失败的原因。
总觉得理论的说得太多,担心大家看得想睡觉,好吧,现在我们再回来看看我们刚才的问题。
----------------------------------------
#include <windows.h>
#include <iostream>
using std::cout;
using std::endl;
unsigned int g_count = 10000;
DWORD WINAPI f1(LPVOID);
DWORD WINAPI f2(LPVOID);
DWORD WINAPI f3(LPVOID);
DWORD WINAPI f4(LPVOID);
int main(){
HANDLE _handle[4];
DWORD _threadID[4];
_handle[0] = CreateThread(NULL,0,f1,NULL,0,&_threadID[0]);
_handle[1] = CreateThread(NULL,0,f2,NULL,0,&_threadID[1]);
_handle[2] = CreateThread(NULL,0,f3,NULL,0,&_threadID[2]);
_handle[3] = CreateThread(NULL,0,f4,NULL,0,&_threadID[3]);
for(int i=0;i<4;i++){
if(_handle[i]){
cout<<"thread "<<_threadID[i]<<" launched\n"<<endl;
CloseHandle(_handle[i]);
}
}
Sleep(40000);
return 0;
}
DWORD WINAPI f1(LPVOID){
while(true){
if(g_count>0){
cout<<"F1: "<<g_count--<<endl;
}
else
break;
}
return 0;
}
DWORD WINAPI f2(LPVOID){
while(true){
if(g_count>0){
cout<<"F2: "<<g_count--<<endl;
}
else
break;
}
return 0;
}
DWORD WINAPI f3(LPVOID){
while(true){
if(g_count>0){
cout<<"F3: "<<g_count--<<endl;
}
else
break;
}
return 0;
}
DWORD WINAPI f4(LPVOID){
while(true){
if(g_count>0){
cout<<"F4: "<<g_count--<<endl;
}
else
break;
}
return 0;
}
------------------------------------------
是不是很简单?不过我想说的是这里还有一个bug,留待下一讲吧,如果大家想要找到这个bug,不妨无限运行下去,你们会看到一个很让人意外的数字出现。
好了,今天我们就简单的尝试一下多线程,如果大家有什么问题,可以直接提问,看到的话一定帮忙解答。