关于在多核计算机上,运用多线程编程,进行科学计算的问题

weibudda 2008-10-03 09:42:54
我运用C++语言,编写程序进行科学计算,用的是八核计算机,Windows系统
具体情况如下:有很多公用的常数,三个很大的数组Fi[750][750][2]和C[750][750][2]和Te[10000];具体的计算简单说就是:根据Fi[750][750][0]和C[750][750][0]和Te[i]先算出Fi[750][750][1],再算出C[750][750][1],然后再算出
Te[i+1](而算Te[i+1]时还要用到刚算出的Fi[750][750][1]和C[750][750][1]),一次循环结束。下一次循环,根据Fi[750][750][1]和C[750][750][1]和Te[i+1]先算出Fi[750][750][0],再算出C[750][750][0],然后再算出Te[i+2]](而算Te[i+2]时还要用到刚算出的Fi[750][750][0]和C[750][750][0]),总之就是[0]和[1]的数组来回颠倒着算,估计至少是10000步吧
我也看了一些多线程方面的书,编了如下的程序,可以说是模拟我说要进行的计算吧,可以运行,但仍有些担心和不满意,希望能给提些意见,毕竟我只是个外行
源代码如下:

#include <iostream>
#include <tchar.h>
#include <windows.h>
using namespace std;

//四个线程分别计算公用数组中的不同段
//每个线程进行相同的计算,但各自乘上一个不同的常数,以区别开
const int Te_Num=10;//t循环次数
//常数
const double con_Fi=20;
const double con_C=19;
const double con_Te=10;

int g_x=0;//全局变量
//公用数组
double Fi[20][2];
double C[20][2];
double Te[Te_Num+1];

CRITICAL_SECTION g_cx;
CRITICAL_SECTION g_cFi;
CRITICAL_SECTION g_cC;
CRITICAL_SECTION g_cTe;

int t=0;//时间变量,

DWORD WINAPI ThreadFun1(LPVOID lpParameter)//计算公用数组中的0~4段
{
//局部变量
double blockFi0;double blockC0;double blockTe0;
double blockFi1;double blockC1;
//把时间t转换为0和1,以便实现对Fi[][][0]和Fi[][][1]轮换互相计算以及C[][][0]和C[][][1]轮换互相计算
int tt=t%2;
int ttt=t%2;

for(int i=0;i<5;i++)
{
//当一个关键代码段长时间运行时,其他线程就会进入等待状态,这会降低应用程序的运行性能
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把公用资源存放在局部变量blockFi0,blockC0,blockTe0中,以最大限度地减少关键代码段运行所花费的时间
blockFi0=Fi[i][tt];
blockC0=C[i][tt];
blockTe0=Te[t];

LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//模仿长时间计算,并把结果存放在临时变量blockFi1,blockC1,blockTe1中
Sleep(200);
blockFi1=1*(blockFi0+blockC0+blockTe0)/con_Fi;
blockC1=1*(blockFi0+blockC0+blockTe0)/con_C;
//
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把结果放回公用数组Fi[],C[],Te[]
Fi[i][ttt]=blockFi1;
C[i][ttt]=blockC1;

LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//改变全局变量g_x的值
EnterCriticalSection(&g_cx);
g_x++;
LeaveCriticalSection(&g_cx);
}
return 0;
}
DWORD WINAPI ThreadFun2(LPVOID lpParameter)//计算公用数组中的5~9段
{
double blockFi0;double blockC0;double blockTe0;
double blockFi1;double blockC1;
for(int i=5;i<10;i++)
{
//把时间t转换为0和1,以便实现对Fi[][][0]和Fi[][][1]轮换互相计算以及C[][][0]和C[][][1]轮换互相计算
int tt=t%2;
int ttt=t%2;
//当一个关键代码段长时间运行时,其他线程就会进入等待状态,这会降低应用程序的运行性能
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把公用资源存放在局部变量blockFi0,blockC0,blockTe0中,以最大限度地减少关键代码段运行所花费的时间
blockFi0=Fi[i][tt];
blockC0=C[i][tt];
blockTe0=Te[t];

LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//模仿长时间计算,并把结果存放在临时变量blockFi1,blockC1,blockTe1中
Sleep(200);
blockFi1=2*(blockFi0+blockC0+blockTe0)/con_Fi;
blockC1=2*(blockFi0+blockC0+blockTe0)/con_C;
//
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把结果放回公用数组Fi[],C[],Te[]
Fi[i][ttt]=blockFi1;
C[i][ttt]=blockC1;

LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//改变全局变量g_x的值
EnterCriticalSection(&g_cx);
g_x++;
LeaveCriticalSection(&g_cx);
}
return 0;
}
DWORD WINAPI ThreadFun3(LPVOID lpParameter)//计算公用数组中的10~14段
{
double blockFi0;double blockC0;double blockTe0;
double blockFi1;double blockC1;
for(int i=10;i<15;i++)
{
//把时间t转换为0和1,以便实现对Fi[][][0]和Fi[][][1]轮换互相计算以及C[][][0]和C[][][1]轮换互相计算
int tt=t%2;
int ttt=t%2;
//当一个关键代码段长时间运行时,其他线程就会进入等待状态,这会降低应用程序的运行性能
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把公用资源存放在局部变量blockFi0,blockC0,blockTe0中,以最大限度地减少关键代码段运行所花费的时间
blockFi0=Fi[i][tt];
blockC0=C[i][tt];
blockTe0=Te[t];

LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//模仿长时间计算,并把结果存放在临时变量blockFi1,blockC1,blockTe1中
Sleep(200);
blockFi1=3*(blockFi0+blockC0+blockTe0)/con_Fi;
blockC1=3*(blockFi0+blockC0+blockTe0)/con_C;
//
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把结果放回公用数组Fi[],C[],Te[]
Fi[i][ttt]=blockFi1;
C[i][ttt]=blockC1;

LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//改变全局变量g_x的值
EnterCriticalSection(&g_cx);
g_x++;
LeaveCriticalSection(&g_cx);
}
return 0;
}
DWORD WINAPI ThreadFun4(LPVOID lpParameter)//计算公用数组中的15~19段
{
double blockFi0;double blockC0;double blockTe0;
double blockFi1;double blockC1;
//把时间t转换为0和1,以便实现对Fi[][][0]和Fi[][][1]轮换互相计算以及C[][][0]和C[][][1]轮换互相计算
int tt=t%2;
int ttt=t%2;
for(int i=15;i<20;i++)
{
//当一个关键代码段长时间运行时,其他线程就会进入等待状态,这会降低应用程序的运行性能
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把公用资源存放在局部变量blockFi0,blockC0,blockTe0中,以最大限度地减少关键代码段运行所花费的时间
blockFi0=Fi[i][tt];
blockC0=C[i][tt];
blockTe0=Te[t];

LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//模仿长时间计算,并把结果存放在临时变量blockFi1,blockC1,blockTe1中
Sleep(200);
blockFi1=4*(blockFi0+blockC0+blockTe0)/con_Fi;
blockC1=4*(blockFi0+blockC0+blockTe0)/con_C;
//
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把结果放回公用数组Fi[],C[],Te[]
Fi[i][ttt]=blockFi1;
C[i][ttt]=blockC1;

LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//改变全局变量g_x的值
EnterCriticalSection(&g_cx);
g_x++;
LeaveCriticalSection(&g_cx);
}
return 0;
}
void main()
{
//初始化Fi,C,Te数组
for(int i=0;i<20;i++)
{
Fi[i][0]=1;Fi[i][1]=1;C[i][0]=0.19;C[i][1]=0.19;
}
Te[0]=900;

HANDLE hThread1;
HANDLE hThread2;
HANDLE hThread3;
HANDLE hThread4;
for(t=0;t<Te_Num;t++)
{
//每次循环都把全局变量g_x置为零
g_x=0;

//初始化CriticalSection
InitializeCriticalSection(&g_cx);
InitializeCriticalSection(&g_cFi);
InitializeCriticalSection(&g_cC);
InitializeCriticalSection(&g_cTe);
//创建线程
hThread1=CreateThread(NULL,0,ThreadFun1,NULL,0,NULL);
hThread2=CreateThread(NULL,0,ThreadFun2,NULL,0,NULL);
hThread3=CreateThread(NULL,0,ThreadFun3,NULL,0,NULL);
hThread4=CreateThread(NULL,0,ThreadFun4,NULL,0,NULL);

CloseHandle(hThread1);
CloseHandle(hThread2);
CloseHandle(hThread3);
CloseHandle(hThread4);

while(g_x<20)//不断查询g_x,主线程等待所有辅助线程的计算完成//这麽处理是不是浪费CPU时间???
Sleep(10);
cout<<"Hello"<<endl;

DeleteCriticalSection(&g_cx);
DeleteCriticalSection(&g_cFi);
DeleteCriticalSection(&g_cC);
DeleteCriticalSection(&g_cTe);

//把时间t转换为0和1,以便实现对Fi[][][0]和Fi[][][1]轮换输出以及C[][][0]和C[][][1]轮换输出,以及Te[t+1]的计算
int ttt=(t+1)%2;
int tt=t%2;

//计算Te[t+1] 主线程会不会和副助主线程冲突 ???
for(int i=0;i<20;i++)
{
Te[t+1]=Te[t]+(Fi[i][tt]+C[i][tt])/con_Te;
}

cout<<g_x<<endl;
for(int i=0;i<20;i++)//主线程输出结果
{
cout<<Fi[i][tt]<<" "<<C[i][tt]<<" "<<Te[t]<<" "<<t<<endl;
}

}
}


...全文
3713 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
weibudda 2008-10-10
  • 打赏
  • 举报
回复
原程序太复杂,此程序只是为了讨论并行算法举的例子。
怎麽动态分配计算的数据段?
zcs302 2008-10-10
  • 打赏
  • 举报
回复
运算过程中 tt和ttt 都没有发生变化啊....而且两者是相等的,少声明一个也行的吧?
还有怎么说明的时候是说用到3三维数组的,但是程序中只是二维的啊,让我百思不得其解,是我水平问题?
看是没怎么看明白的了,只是提出点疑问
要是动态分配计算的数据段,是不是会更好的啊?
weibudda 2008-10-08
  • 打赏
  • 举报
回复
#include <iostream>
#include <fstream>
#include <tchar.h>
#include <windows.h>
#include<cstdlib>
using namespace std;
const int Te_Num=200;//t循环次数
//常数
const double con_Fi=20;
const double con_C=19;
const double con_Te=10;

int g_x=0;//全局变量
//公用数组
double Fi[20][2];
double C[20][2];
double Te[Te_Num+1];

CRITICAL_SECTION g_cx;
CRITICAL_SECTION g_cFi;
CRITICAL_SECTION g_cC;
CRITICAL_SECTION g_cTe;


//定义事件对象句柄
HANDLE g_hEvent;//用于计算Fi[]和C[]
HANDLE g_outputEvent;//用于计算Te[]以及输出结果
HANDLE g_mainEvent;//用于控制主线程的继续

struct ThreadParaNode{
int i_begin;
int i_end;
};
DWORD WINAPI ThreadFun(LPVOID para)//用于计算Fi[]和C[]
{
ThreadParaNode *pThreadPara = (ThreadParaNode*)para;


//定义局部变量
double blockFi0;double blockC0;double blockTe0;
double blockFi1;double blockC1;

for(int t=0;t <Te_Num;t++)
{
WaitForSingleObject(g_hEvent,INFINITE);

//计算部分

for(int i=pThreadPara->i_begin;i<pThreadPara->i_end;i++)
{
//把时间t转换为0和1,以便实现对Fi[][][0]和Fi[][][1]轮换互相计算以及C[][][0]和C[][][1]轮换互相计算
int tt=t%2;
int ttt=t%2;

//当一个关键代码段长时间运行时,其他线程就会进入等待状态,这会降低应用程序的运行性能
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);

//把公用资源存放在局部变量blockFi0,blockC0,blockTe0中,以最大限度地减少关键代码段运行所花费的时间
blockFi0=Fi[i][tt];
blockC0=C[i][tt];
blockTe0=Te[t];

LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);

//模仿长时间计算,并把结果存放在临时变量blockFi1,blockC1,blockTe1中
blockFi1=2*(blockFi0+blockC0+blockTe0)/con_Fi;
blockC1=2*(blockFi0+blockC0+blockTe0)/con_C;
//
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把结果放回公用数组Fi[],C[],Te[]
Fi[i][ttt]=blockFi1;
C[i][ttt]=blockC1;

LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//改变全局变量g_x的值
EnterCriticalSection(&g_cx);
g_x++;

//监视g_x
while(g_x >=20)
{
g_x=0;

//而把事件g_hEvent(用于计算Fi[]和C[])设置为无信号状态
//把事件g_outputEvent(用于计算Te[]以及输出结果)设置为有信号状态
ResetEvent(g_hEvent);
SetEvent(g_outputEvent);

cout<<"Hello"<<endl;
}
LeaveCriticalSection(&g_cx);

}


}

delete pThreadPara;
return 0;
}
DWORD WINAPI ThreadFun_output(LPVOID para)//用于计算Te[]以及输出结果
{
ofstream outfile("data.txt",ios::out);
for(int t=0;t <Te_Num;t++)
{
WaitForSingleObject(g_outputEvent,INFINITE);

//把时间t转换为0和1,以便实现对Fi[][][0]和Fi[][][1]轮换输出以及C[][][0]和C[][][1]轮换输出,以及Te[t+1]的计算
int ttt=(t+1)%2;
int tt=t%2;

//计算Te[t+1]
for(int i=0;i <20;i++)
{
Te[t+1]=Te[t]+(Fi[i][tt]+C[i][tt])/con_Te;
}

//输出结果
cout<<g_x<<endl;
outfile<<g_x<<endl;

for(int i=0;i <20;i++)//主线程输出结果
{
cout<<Fi[i][tt]<<" "<<C[i][tt]<<" "<<Te[t]<<" "<<t<<endl;
outfile<<Fi[i][tt]<<" "<<C[i][tt]<<" "<<Te[t]<<" "<<t<<endl;
}

//把事件g_outputEvent(用于计算Te[]以及输出结果)设置为无信号状态
//而把事件g_hEvent(用于计算Fi[]和C[])设置为有信号状态
ResetEvent(g_outputEvent);
SetEvent(g_hEvent);
if(t>=Te_Num-1)
SetEvent(g_mainEvent);
}
outfile.close();
return 0;
}
void main()
{
//初始化Fi,C,Te数组
for(int i=0;i <20;i++)
{
Fi[i][0]=1;Fi[i][1]=1;C[i][0]=0.19;C[i][1]=0.19;
}
Te[0]=900;

//初始化CriticalSection
InitializeCriticalSection(&g_cx);
InitializeCriticalSection(&g_cFi);
InitializeCriticalSection(&g_cC);
InitializeCriticalSection(&g_cTe);

//创建事件
g_hEvent=CreateEvent(NULL,TRUE,TRUE,NULL);
g_outputEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
g_mainEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

//创建线程
HANDLE hThread_output=CreateThread(NULL, 0, ThreadFun_output, NULL, 0, NULL);
HANDLE hThread[4];
for(int i=0;i <4;i++)//利用循环建立四个进行相同运算,但是分别算Fi[]和C[]不同区段的线程
{
ThreadParaNode *pThreadPara = new ThreadParaNode;
pThreadPara->i_begin = 5 * i;
pThreadPara->i_end = 5 * i + 5;
hThread[i]=CreateThread(NULL, 0, ThreadFun, pThreadPara, 0, NULL);
}

WaitForSingleObject(g_mainEvent,INFINITE);

//关闭内核对象
for(int i=0;i <4;i++)
{
CloseHandle(hThread[i]);
}
CloseHandle(hThread_output);

//清除临界区
DeleteCriticalSection(&g_cx);
DeleteCriticalSection(&g_cFi);
DeleteCriticalSection(&g_cC);
DeleteCriticalSection(&g_cTe);
}
weibudda 2008-10-08
  • 打赏
  • 举报
回复
谢谢各位的提醒
我把上面的程序改进了一下,希望各位再给看一看
拜托,拜托

源代码如下
vioy 2008-10-07
  • 打赏
  • 举报
回复
要提高对多核的利用效率,首先要提高算法的并行度。
你的算法本身限定了只能顺序计算。

程序中的Fi和C数组好像不是算法中的3维数组,而是2维的?没看明白程序中的意思。

根据你的算法,觉得应该把根据Fi、C和Te[i]计算Fi和C的算法以及后面的计算Te[i+1]的算法提高并行度,让多线程计算才能提高速度。
vioy 2008-10-07
  • 打赏
  • 举报
回复
关注下
AthlonxpX86 2008-10-06
  • 打赏
  • 举报
回复
你的代码多核应用效能很低的,甚至低于单核运行的速度
问题
1:循环数任务量少还要用临界区,信号量都是毫秒级的一般都用于等待I\O操作,用在这里只能保证算法正确,但大大降低运行效率,并行算法要使用多线程首先界要考虑的就是避免信号亮的使用。
解决方法是使用模板元编程方法将任务(循环间不相关的循环)在编译期分派规划到不同线程,以此解决运行期中因为任务规划而使用信号亮,另外OPENMP也是属于编译期解循环并行化的技术,相对模板元编程他更加专业,更加简单,但是需要编译器支持。
2: 运行时开线程这个操作的时间可能都大于算法本身的时间,一定要在程序初始化时就确定好
xsq2132276 2008-10-06
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 weibudda 的回复:]
还有一个问题就是每次循环都建一个线程,这样做是不是不好?
[/Quote]
创建线程有一定的系统开销,不过还是要看该线程完成的任务量,两者权衡吧。
jameshooo 2008-10-03
  • 打赏
  • 举报
回复
要充分利用多核特性,使用OpenMP库,可以在代码中指定使用的核心。
weibudda 2008-10-03
  • 打赏
  • 举报
回复
还有一个问题就是每次循环都建一个线程,这样做是不是不好?
phisherr 2008-10-03
  • 打赏
  • 举报
回复
我运用C++语言,编写程序进行科学计算,用的是八核计算机,Windows系统 
具体情况如下:有很多公用的常数,三个很大的数组Fi[750][750][2]和C[750][750][2]和Te[10000];具体的计算简单说就是:根据Fi[750][750][0]和C[750][750][0]和Te[i]先算出Fi[750][750][1],再算出C[750][750][1],然后再算出
Te[i+1](而算Te[i+1]时还要用到刚算出的Fi[750][750][1]和C[750][750][1]),一次循环结束。下一次循环,根据Fi[750][750][1]和C[750][750][1]和Te[i+1]先算出Fi[750][750][0],再算出C[750][750][0],然后再算出Te[i+2]](而算Te[i+2]时还要用到刚算出的Fi[750][750][0]和C[750][750][0]),总之就是[0]和[1]的数组来回颠倒着算,估计至少是10000步吧
我也看了一些多线程方面的书,编了如下的程序,可以说是模拟我说要进行的计算吧,可以运行,但仍有些担心和不满意,希望能给提些意见,毕竟我只是个外行
源代码如下:

#include <iostream>
#include <tchar.h>
#include <windows.h>
using namespace std;

//四个线程分别计算公用数组中的不同段
//每个线程进行相同的计算,但各自乘上一个不同的常数,以区别开
const int Te_Num=10;//t循环次数
//常数
const double con_Fi=20;
const double con_C=19;
const double con_Te=10;

int g_x=0;//全局变量
//公用数组
double Fi[20][2];
double C[20][2];
double Te[Te_Num+1];

CRITICAL_SECTION g_cx;
CRITICAL_SECTION g_cFi;
CRITICAL_SECTION g_cC;
CRITICAL_SECTION g_cTe;

int t=0;//时间变量,

DWORD WINAPI ThreadFun1(LPVOID lpParameter)//计算公用数组中的0~4段
{
//局部变量
double blockFi0;double blockC0;double blockTe0;
double blockFi1;double blockC1;
//把时间t转换为0和1,以便实现对Fi[][][0]和Fi[][][1]轮换互相计算以及C[][][0]和C[][][1]轮换互相计算
int tt=t%2;
int ttt=t%2;

for(int i=0;i <5;i++)
{
//当一个关键代码段长时间运行时,其他线程就会进入等待状态,这会降低应用程序的运行性能
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把公用资源存放在局部变量blockFi0,blockC0,blockTe0中,以最大限度地减少关键代码段运行所花费的时间
blockFi0=Fi[i][tt];
blockC0=C[i][tt];
blockTe0=Te[t];

LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//模仿长时间计算,并把结果存放在临时变量blockFi1,blockC1,blockTe1中
Sleep(200);
blockFi1=1*(blockFi0+blockC0+blockTe0)/con_Fi;
blockC1=1*(blockFi0+blockC0+blockTe0)/con_C;
//
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把结果放回公用数组Fi[],C[],Te[]
Fi[i][ttt]=blockFi1;
C[i][ttt]=blockC1;

LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//改变全局变量g_x的值
EnterCriticalSection(&g_cx);
g_x++;
LeaveCriticalSection(&g_cx);
}
return 0;
}
DWORD WINAPI ThreadFun2(LPVOID lpParameter)//计算公用数组中的5~9段
{
double blockFi0;double blockC0;double blockTe0;
double blockFi1;double blockC1;
for(int i=5;i <10;i++)
{
//把时间t转换为0和1,以便实现对Fi[][][0]和Fi[][][1]轮换互相计算以及C[][][0]和C[][][1]轮换互相计算
int tt=t%2;
int ttt=t%2;
//当一个关键代码段长时间运行时,其他线程就会进入等待状态,这会降低应用程序的运行性能
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把公用资源存放在局部变量blockFi0,blockC0,blockTe0中,以最大限度地减少关键代码段运行所花费的时间
blockFi0=Fi[i][tt];
blockC0=C[i][tt];
blockTe0=Te[t];

LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//模仿长时间计算,并把结果存放在临时变量blockFi1,blockC1,blockTe1中
Sleep(200);
blockFi1=2*(blockFi0+blockC0+blockTe0)/con_Fi;
blockC1=2*(blockFi0+blockC0+blockTe0)/con_C;
//
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把结果放回公用数组Fi[],C[],Te[]
Fi[i][ttt]=blockFi1;
C[i][ttt]=blockC1;

LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//改变全局变量g_x的值
EnterCriticalSection(&g_cx);
g_x++;
LeaveCriticalSection(&g_cx);
}
return 0;
}
DWORD WINAPI ThreadFun3(LPVOID lpParameter)//计算公用数组中的10~14段
{
double blockFi0;double blockC0;double blockTe0;
double blockFi1;double blockC1;
for(int i=10;i <15;i++)
{
//把时间t转换为0和1,以便实现对Fi[][][0]和Fi[][][1]轮换互相计算以及C[][][0]和C[][][1]轮换互相计算
int tt=t%2;
int ttt=t%2;
//当一个关键代码段长时间运行时,其他线程就会进入等待状态,这会降低应用程序的运行性能
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把公用资源存放在局部变量blockFi0,blockC0,blockTe0中,以最大限度地减少关键代码段运行所花费的时间
blockFi0=Fi[i][tt];
blockC0=C[i][tt];
blockTe0=Te[t];

LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//模仿长时间计算,并把结果存放在临时变量blockFi1,blockC1,blockTe1中
Sleep(200);
blockFi1=3*(blockFi0+blockC0+blockTe0)/con_Fi;
blockC1=3*(blockFi0+blockC0+blockTe0)/con_C;
//
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把结果放回公用数组Fi[],C[],Te[]
Fi[i][ttt]=blockFi1;
C[i][ttt]=blockC1;

LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//改变全局变量g_x的值
EnterCriticalSection(&g_cx);
g_x++;
LeaveCriticalSection(&g_cx);
}
return 0;
}
DWORD WINAPI ThreadFun4(LPVOID lpParameter)//计算公用数组中的15~19段
{
double blockFi0;double blockC0;double blockTe0;
double blockFi1;double blockC1;
//把时间t转换为0和1,以便实现对Fi[][][0]和Fi[][][1]轮换互相计算以及C[][][0]和C[][][1]轮换互相计算
int tt=t%2;
int ttt=t%2;
for(int i=15;i <20;i++)
{
//当一个关键代码段长时间运行时,其他线程就会进入等待状态,这会降低应用程序的运行性能
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把公用资源存放在局部变量blockFi0,blockC0,blockTe0中,以最大限度地减少关键代码段运行所花费的时间
blockFi0=Fi[i][tt];
blockC0=C[i][tt];
blockTe0=Te[t];

LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//模仿长时间计算,并把结果存放在临时变量blockFi1,blockC1,blockTe1中
Sleep(200);
blockFi1=4*(blockFi0+blockC0+blockTe0)/con_Fi;
blockC1=4*(blockFi0+blockC0+blockTe0)/con_C;
//
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把结果放回公用数组Fi[],C[],Te[]
Fi[i][ttt]=blockFi1;
C[i][ttt]=blockC1;

LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//改变全局变量g_x的值
EnterCriticalSection(&g_cx);
g_x++;
LeaveCriticalSection(&g_cx);
}
return 0;
}
void main()
{
//初始化Fi,C,Te数组
for(int i=0;i <20;i++)
{
Fi[i][0]=1;Fi[i][1]=1;C[i][0]=0.19;C[i][1]=0.19;
}
Te[0]=900;

HANDLE hThread1;
HANDLE hThread2;
HANDLE hThread3;
HANDLE hThread4;
for(t=0;t <Te_Num;t++)
{
//每次循环都把全局变量g_x置为零
g_x=0;

//初始化CriticalSection
InitializeCriticalSection(&g_cx);
InitializeCriticalSection(&g_cFi);
InitializeCriticalSection(&g_cC);
InitializeCriticalSection(&g_cTe);
//创建线程
hThread1=CreateThread(NULL,0,ThreadFun1,NULL,0,NULL);
hThread2=CreateThread(NULL,0,ThreadFun2,NULL,0,NULL);
hThread3=CreateThread(NULL,0,ThreadFun3,NULL,0,NULL);
hThread4=CreateThread(NULL,0,ThreadFun4,NULL,0,NULL);

CloseHandle(hThread1);
CloseHandle(hThread2);
CloseHandle(hThread3);
CloseHandle(hThread4);

while(g_x <20)//不断查询g_x,主线程等待所有辅助线程的计算完成//这麽处理是不是浪费CPU时间???
Sleep(10);
cout < <"Hello" < <endl;

DeleteCriticalSection(&g_cx);
DeleteCriticalSection(&g_cFi);
DeleteCriticalSection(&g_cC);
DeleteCriticalSection(&g_cTe);

//把时间t转换为0和1,以便实现对Fi[][][0]和Fi[][][1]轮换输出以及C[][][0]和C[][][1]轮换输出,以及Te[t+1]的计算
int ttt=(t+1)%2;
int tt=t%2;

//计算Te[t+1] 主线程会不会和副助主线程冲突 ???
for(int i=0;i <20;i++)
{
Te[t+1]=Te[t]+(Fi[i][tt]+C[i][tt])/con_Te;
}

cout < <g_x < <endl;
for(int i=0;i <20;i++)//主线程输出结果
{
cout < <Fi[i][tt] < <" " < <C[i][tt] < <" " < <Te[t] < <" " < <t < <endl;
}

}
}
phisherr 2008-10-03
  • 打赏
  • 举报
回复
        CloseHandle(hThread1); 
CloseHandle(hThread2);
CloseHandle(hThread3);
CloseHandle(hThread4);

while(g_x <20)//不断查询g_x,主线程等待所有辅助线程的计算完成//这麽处理是不是浪费CPU时间???
Sleep(10);


查询应该在关闭前面把

15,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧