C/C++ 简单的多线程编程 |
#include <iostream> using namespace std; DWORD WINAPI Thread1Proc( LPVOID lpParameter); //线程的执行函数 DWORD WINAPI Thread2Proc( LPVOID lpParameter); //线程的执行函数 int a; int b; int c; int temp(0); int sum(0); int main() { a=1; b=2; c=3; HANDLE hThread1=CreateThread(NULL,0,Thread1Proc,NULL,0,NULL); //『注意2』创建线程1 HANDLE hThread2=CreateThread(NULL,0,Thread2Proc,NULL,0,NULL); //创建线程2 CloseHandle(hThread1); //关闭标识线程1的句柄 CloseHandle(hThread2); //关闭标识线程2的句柄 Sleep(5); //『注意3』主线程放弃执行权,睡眠毫秒,以使线程和线程得到执行机会 sum=temp; //主线程的执行语句 cout<<"sum="<<sum<<endl; //主线程的执行语句 return 0; } DWORD WINAPI Thread1Proc( LPVOID lpParameter) { temp=a+b; return 0; } DWORD WINAPI Thread2Proc( LPVOID lpParameter) { temp+=c; return 0; } 代码说明:本代码简单演示了多线程的创建方法。程序用包括主线程在内的三个线程共同完成sum=a+b+c并输出计算结果的功能。其中,线程1完成a+b这一步,线程2完成将a+b的结果与c相加这一步,主线程完成输出计算结果这一步。整个程序很简单,一目了然,但是,依然有几个地方需要注意: 「注意1」由于创建线程所使用的函数CreateThread()是windows API函数,所以,必须包含头文件windows.h 「注意2」CreateThread()函数有一个HANDLE 类型的返回值,用来标识创建的线程,因此,应该定义一个HANDLE类型的变量用于保存这个句柄(不是必须)。线程创建完成之后,如果不需要使用这个句柄变量,应当将其关闭,以释放系统资源。关闭句柄的方法是调用CloseHandle()函数。 「注意3」这里的Sleep()函数的作用是使主线程放弃执行机会,让其它线程开始执行。因为这个程序主线程内运行的代码很短,就两条短语句,同常情况,这两条语句在一个系统时间片内就能跑完,然后就执行return语句返回,主线程就运行结束了。主线程一结束,程序就终止,线程1和线程2将再也得不到执行机会。我们可以将Sleep()注释起来,然后运行程序,观察打印出来的sum值即可以发现线程1和线程2是否得到运行机会。当然,Sleep()不是必须的,这从系统调度线程的方式可以看出来,多线程程序在开始运行时,系统会首先让主线程执行一段时间(时间片),如果主线程在这个时间段内将所有代码都执行完了,程序就结束,否则,就将主线程挂起,然后让其他线程执行同样的一段时间,时间到了之后,该线程挂起,又返回主线程开始执行,主线程再执行同样的一段时间,然后再挂起,跳到其他线程执行,如此不断循环,直到主线程完全执行完毕为止。由此可见,要想让非主线程能够被完整执行,那么只要使它获得的时间片的总和大于或等于该线程连续执行完毕所需要的时间即可。基于此原理,我们想到,只要让主线程被多次挂起即可使非主线程获得多个执行时间片。那么,如何让主线程多次被挂起呢?很简单,只要让主线程连续执行完毕所需要的时间是系统时间片的N倍即可,具体N等于多少合适,那需要视其他线程完整执行需要多少时间。我们实验一下,把调用Sleep()那行代码注释起来,然后在那里写上如下代码: //Sleep(5); for(int i=0;i<1000000;i++){} 这个for循环什么事也不做,就是延长主线程的执行时间,使主线程在一个时间片里执行不完,分成在若干个时间片里执行。运行程序,可以发现,输出的sum值等于6,符合预期,说明,线程1和线程2都得到了执行。
运行之前需要做一些配置: 1.下载PTHREAD的WINDOWS开发包 pthreads-w32-2-4-0-release.exe(任何一个版本均可)http://sourceware.org/pthreads-win32/ ,解压到一个目录。 2.找到include和lib文件夹,下面分别把它们添加到VC++6.0的头文件路径和静态链接库路径下面: a).Tools->Options,选择Directory页面,然后在Show directories for:中选择Include files(默认) 在Directories中添加include的路径。在Show directories for:中选择Library files, 在Directories中添加lib的路径。 b).Project->Settings,选择Link页面,然后将lib下的*.lib文件添加到Object/library Modules, 各lib文件以空格隔开。 c).将lib下的*.dll文件复制到工程目录下,即根目录。 3.代码
|