第一次写技术博客,写得不好以及疏漏,真心希望各位留言讨论。
本程序要想实现第二个比第一个运行得快还需有个硬件条件:电脑需要是双核及以上。如果是单核,那么虽然有了多线程,也因为无法将多个线程分不到多个核上运行而无法提高运行速度。执行环境是Win7.开发环境是VC6.0
本程序用到的与线程有关的API只有:_beginthreadex()。各位和我一样的新手朋友有兴趣可以在自己的机子上跑一跑下面的程序,环境:VC6.0(把我的代码直接粘贴就可以,但最开始编译报错的话,是要进行设置的,把错误粘贴到百度下就可以解决,我也遇到过,百度有解决方案,很好解决)
我的程序很简单,首先执行第一个for()循环,这个for()循环有两层,没什么特别意思,只是让这个for循环消耗的时间更久一些。第二个for同理,两个for()循环其实完全一样,这样是为了待会将其改造成多线程版本会方便。
程序如下:
#include<iostream>
#include<time.h>
using namespace std;
void main()
{
clock_t start, end;//这两个变量记录运行时间起始和结束时间
double total_time;
int result;
int t1=0,t2=0;
start=clock();//开始计时
for(int i1=0;i1<100000;i1++)
{
for(int j=0;j<10000;j++)
t1++;
}
for(int i2=0;i2<100000;i2++)//注意这个for()循环待会要作为线程并发执行的
{
for(int k=0;k<10000;k++)
t2++;
}
end = clock();//结束计时
result=t1+t2;
total_time=(double)(end-start);//计算一共花了多少时间
cout<<"reuslt is : "<<result<<" total time is : "<<total_time;
}
结果如下:result is : 2000000000 total time is : 6267 (不要关注result is : 2000000000 ,关注后面花费的时间6267,)
我又运行了几次,结果如下(只写total time):
total time is : 6848
total time is : 6097
total time is : 6238
现在我想加速这个程序。观察这个程序,我们注意到第二个for循环与第一个for循环可以并行执行,因为第二个for循环的执行不需要用到第一个for()循环执行的结果,所以可以并发。而并发又有什么好处呢?并发可以使任务在多个处理器上同时运行!(原来这个程序只是在一个处理器上执行)。我这里是用线程来实现并行(所以是多个线程在多个处理器上同时运行)。那么怎么把第二个for()交给另一个线程去执行呢,联想到线程需要一个运行函数,所以我们将第二个for()循环放到一个函数里就行了。
修改后的代码如下:
#include<iostream>
#include<time.h>
#include<windows.h>
#include<process.h>
using namespace std;
int thread2_end=0;//在主程序中要通过这个变量来等待子线程执行结束,子线程结束之后,才能加上子线程2的执行结果t2。
int t2=0;//设置为全局变量是因为主程序要访问这个值。
unsigned __stdcall thread2(void*)//不错,是的,这个函数的返回值有点唬人,不用管它,它一点不影响程序执行,你可以直接将它看成void,直接无视它。
{
for(int i2=0;i2<100000;i2++)
{
for(int k=0;k<10000;k++)
t2++;
}
thread2_end=1;
return 0;
}
void main()
{
clock_t start,end;
HANDLE hThread2;
unsigned int threadID1;
int t1=0;
double total_time;
start=clock();
hThread2 = (HANDLE)_beginthreadex(NULL, 0, &thread2, NULL, 0, &threadID1);
for(int i1=0;i1<100000;i1++)
{
for(int j=0;j<10000;j++)
t1++;
}
while(thread2_end==0)//若子线程先执行完,那么由于子线程将thread2_end置为1,所以当主程序执行到这,就可以继续向下执行;若主程序执行完for循环,子线程还没执行完,主程序会在这里循环等待子线程执行完。
{
}
t1=t1+t2;
end=clock();
total_time=(double)(end-start);
cout<<"result is: "<<t1<<" total time is :"<<total_time<<endl;
}
运行结果如下:
result is :2000000000 total time is :3268
再运行几遍,结果如下(同样,每次result都是2000000000,就不写了,只写total time):
total time is :3304
total time is :3379
total time is :2996
total time is :3017
这个程序将第一个程序中先运行完第一个for循环,再运行第二个for循环的串行执行方式,通过应用线程的方式改成了
第一个for循环和第二个for循环同时运行的并行执行方式,(这样,操作系统会自动将生成的子线程分配到另一个处理器上去执行(当然啦,你的计算机必须得是双核及以上...),也就是把那个for循环分配到另一个处理器上去执行,而第一个程序中另一个处理器一直是空闲的!)。理论上中会节约一半左右的时间,事实上,执行结果也印证了这一点。
后话,可以在执行程序同时打开WINDOWS资源管理器,执行第一个程序时,如果你的计算机是双核的,你会注意到CPU利用率在50%左右(以双核计算机为例),而执行第二个程序,CPU利用率是100%。
我的第一个程序和第二个程序的执行时,CPU运行情况如下(通过WINDOWS资源管理器得到):
第一个程序:
第二个程序: