多线程问题
正在做一个指纹比对的程序,分为客户端和服务端。客户端上传指纹数据到服务端进行比较,客户端大概有1000多条数据,服务端大概有几十万条数据。如果不采用多线程这将会是一个十几小时的工作。想用多线程来摆脱困境。现在只是在客户端加几十条数据,我加上多线程之后发现比单线程还要慢,望请各位大虾帮帮小弟
public void Sync()
{
try
{
int CacheSize=CacheCount;
int Score=8;
int ProcessNum=0;
DataTable[] dataarr=new DataTable[RecordCount/(PagerCount==0?RecordCount:PagerCount)];
DataSet dsSource=new DataSet();
DateTime dt1=DateTime.Now;
this.Refresh();
DateTime dts=DateTime.Now;
if(ProgressBarForm.LogFlag)
log.Write("----------Step 1:开始读取FP服务器时间:"+dts+"--------------------\r\n");
this.Refresh();
dataarr[0]=CandAdditional_FP.GetAllFinger(this.RecordCount);
recordCount=dataarr[0].Rows.Count;
k=new int[(RecordCount/CacheSize)+(RecordCount%CacheSize!=0?1:0)];
for(int j=0;j<k.Length;j++)
{
k[j]=axZKFPEngX2.CreateFPCacheDB();//创建指纹比对缓存
}
DateTime dte=DateTime.Now;
log.Write("----------Step 1:结束读取FP服务器时间:"+dte+",共花了:"+new DateTime(dte.Ticks-dts.Ticks).ToString("mm:ss.mmm")+"\r\n");
DateTime CacheTimeS=DateTime.Now;
dts=DateTime.Now;
int t=-1;
int count=-1;
for(int i=0;i<dataarr.Length;i++)
{
t=Convert.ToInt32(Math.Round(Convert.ToDouble(count/CacheSize)).ToString());
try
{//Convert.ToInt32(dataarr[i].Rows[j][0])
axZKFPEngX2.AddRegTemplateStrToFPCacheDB(k[t],Convert.ToInt32(dataarr[i].Rows[j][0]),dataarr[i].Rows[j]["FPKey1"].ToString().Trim());
}
catch(Exception ee){MessageBox.Show(ee.Message+ee.StackTrace+"\r\n"+dataarr[i].Rows[j][0]+"\r\n"+dataarr[i].Rows[j]["FPKey1"]+"\r\n");};
//将数据写入比较缓存
}
dataarr=null;
dte=DateTime.Now;
dtC=CandAdditional_FP_C.SelectByWhere(" and FPKey1<>''",ThreadCount);
dtCCount=dtC.Rows.Count;
GC.Collect();
DateTime dt3=DateTime.Now;
log.Write("----------Step 3:开始指纹比对:"+dte+"\r\n");
if(ThreadFlag)//判断是否为多线程
{
//多线程操作
timer1=new System.Threading.Timer(new TimerCallback(OnTimer),k,0,1000);
}
else
{
//单线程操作
}
if(ThreadFlag)
{
ev.WaitOne();
}
DateTime dt2=DateTime.Now;
log.Write("----------Step 3:结束指纹比对:"+dt2+",共花了:"+new DateTime(dt2.Ticks-dt3.Ticks).ToString("mm:ss.mmm")+"\r\n");
}
catch(Exception ee){MessageBox.Show(ee.Message+ee.StackTrace);if(LogFlag){log.Write("出错:"+ee.Message+"\r\n"+ee.StackTrace);log.Close();}}
}
private static void OnTimer(object state)
{
lock(typeof(CompareFingerPrint))
{
if((CompareFingerPrint.instanceCount<RunCount)&&(startCount<dtCCount))
{
while(startCount<=dtCCount)
{
Ergs s=new Ergs();
s.k=(int[])state;
s.dr=dtC.Rows[startCount];
s.count=dtC.Rows.Count;
s._ev=ev;
s.i=startCount;
CompareFingerPrint scanIt1=new CompareFingerPrint(s.dr,s.i,s.count,s.k,s._ev);
scanIt1.DoScan();
startCount++;
}
if(CompareFingerPrint.instanceCount>=RunCount || startCount+1>=dtCCount)break;
}
}
if(startCount>=dtCCount){CompareFingerPrint.ShouldStop=true;timer1.Dispose();}
}
public class Ergs
{
public DataRow dr;
public int i;
public int count;
public int[] k;
public ManualResetEvent _ev;
}
public class CompareFingerPrint
{
private ManualResetEvent ev;
private Thread thread;
public static int instanceCount=0; //同时存在的对象个数
public static bool ShouldStop=false;
private int i;
public string Can_key;
public string FPkey1;
private int[] SelfCacheUsage;
public static int[] CacheUsage;
int[] k;
int Score=8;
int ProcessNum=0;
int count;
public CompareFingerPrint(DataRow dr,int i,int count,int[] k,ManualResetEvent _ev)
{
this.Can_key=dr[0].ToString();
this.FPkey1=dr["FPKey1"].ToString();
this.i=i;
this.count=count;
this.k=k;
CacheUsage=new int[k.Length];
SelfCacheUsage=new int[k.Length];
ev=_ev;
thread=new Thread(new ThreadStart(target));
lock(typeof(CompareFingerPrint)){ instanceCount++; } //同时存在的对象个数加一
}
public void DoScan()
{
thread.Start();
}
private void target()
{
try
{
string temp=FPkey1;//dtC.Rows[i]["FPKey1"].ToString();
dts=DateTime.Now;
while(DoFinish())
{
int[] arr=GetCache();
try
{
if(arr[0]!=-1)
{
ProgressBarForm.log.Write("第"+Convert.ToString(i+1)+"个:"+this.Can_key+"开始第"+arr[0]+"个Cache比对");
//进行指纹比对,单线程下比完20000条需要5秒钟左右
result=ProgressBarForm.axZKFPEngX2.IdentificationFromStrInFPCacheDB(arr[1],temp,ref Score,ref ProcessNum);
CacheUsage[arr[0]]=0;
SelfCacheUsage[arr[0]]=1;
ProgressBarForm.log.Write("第"+Convert.ToString(i+1)+"个:"+this.Can_key+"结束第"+arr[0]+"个Cache比对");
}
}
catch(Exception ee){MessageBox.Show(ee.Message+ee.StackTrace+"\r\n"+i);CacheUsage[arr[0]]=0;break;};
}
}
catch(Exception e){MessageBox.Show(e.Message+e.StackTrace);}
finally
{
lock(typeof(CompareFingerPrint))
{
GC.Collect();
if((--instanceCount==0)&&(CompareFingerPrint.ShouldStop)) {ev.Set();ProgressBarForm.canExit=true;} //同时存在的对象个数减一
}
}
}
private bool DoFinish()
{
for(int i=0;i<SelfCacheUsage.Length;i++)
{
if(SelfCacheUsage[i]==0)
{
return true;
}
}
return false;
}
private int[] GetCache()
{
lock(this)
{
for(int i=0;i<CacheUsage.Length;i++)
{
if(CacheUsage[i]==0 && SelfCacheUsage[i]==0)
{
CacheUsage[i]=1;
return new int[]{i,k[i]};
}
}
return new int[]{-1,-1};
}
}
}
问题点数:100、回复次数:23Top
1 楼Knight94(愚翁)回复于 2006-08-14 20:51:15 得分 0
代码太长,你说说你的主要流程
多线程不一定有助于提高效率。Top
2 楼hdt(倦怠)回复于 2006-08-14 20:51:20 得分 0
可以使用异步操作
Top
3 楼chrislv(小吕)回复于 2006-08-14 20:56:17 得分 0
从服务器取出20W条数据,放到指纹比对缓存,然后再取出客户端的指纹数据大概1000多条。
单线程情况是循环1000次,就是把客户端的一条条数据与缓存比对。一条大概是一分钟。想用多线程节省时间。。。Top
4 楼Knight94(愚翁)回复于 2006-08-14 21:02:39 得分 0
那你首先想想对于一条记录处理,哪些是可以同步操作,哪些是不需要的。Top
5 楼chrislv(小吕)回复于 2006-08-14 22:42:35 得分 0
有没有什么好介绍呀???搞了几天头晕死了。。。。Top
6 楼coolstarhty(语言多了,编程不好学啊)回复于 2006-08-14 22:56:38 得分 10
想用多线程节省时间。。。
----------------------------------------
使用多线程并不能节省时间,因为CPU最大的工作频率是一定的,
使用多线程只是为不同的程序比较合理地安排运行时间,是多个程序看起来是同时运行。
要想快,要考虑的是如何提高硬件性能,不能无法考虑硬件因素,只能优化程序了。Top
7 楼pyuan(菜鸟)回复于 2006-08-14 23:28:45 得分 0
建义楼主升级电脑。。。。。。Top
8 楼kkbspod(我被可乐淹死了)回复于 2006-08-14 23:30:17 得分 0
多线程是为了高效使用软硬件资源,如果你的这些资源都已经满负荷运转了,再用多线程只会越用越慢Top
9 楼chrislv(小吕)回复于 2006-08-15 10:00:06 得分 0
那本身我写的代码能不能发挥作用,各位帮帮忙Top
10 楼cancerser(都是混饭吃,记得要结帖)回复于 2006-08-15 10:22:19 得分 0
指纹对比 本身就很毫资源的,要真想提高效率就得分布式处理了Top
11 楼thirdman(大肥猪)回复于 2006-08-15 11:31:15 得分 0
是图像比对嘛?你将图像特征数字化了嘛,然后建立快照啊。Top
12 楼chrislv(小吕)回复于 2006-08-15 11:34:44 得分 0
是字符串的,指纹控件提供了方法对比的。Top
13 楼ProjectDD()回复于 2006-08-15 11:41:56 得分 10
按MSDN标准文档的说法多线程可能 会因为线程过多,或其它方面的复杂原因而“降低”运行效率,多线程增加了,线程协调,和管理方面的成本,当线程过多时会极大的加重运行和资源方面的“成本”而且可能会发生复杂问题,大概 多线程更适合于同时完成多个任务,而不是增益运行效率,效率方面仅主要信赖于硬件,配置方面。Top
14 楼chrislv(小吕)回复于 2006-08-15 15:38:04 得分 0
不知道还有没有其它的解决方案???各位大虾帮帮我呀Top
15 楼Knight94(愚翁)回复于 2006-08-15 15:43:53 得分 30
to 不知道还有没有其它的解决方案???
其实大家已经说得很清楚了。
你首先要分析你现在处理的瓶颈在哪儿,而这个瓶颈是否能通过多线程来改善。Top
16 楼chrislv(小吕)回复于 2006-08-15 15:45:06 得分 0
谢谢各位。Top
17 楼chrislv(小吕)回复于 2006-08-15 15:51:08 得分 0
to hdt(倦怠) 可以使用异步操作
如何操作?可否告之。。。Top
18 楼softbunny(软件兔)回复于 2006-08-15 16:08:48 得分 20
如果你比对一个指纹时是一直在计算的话,那线程越多速度越慢.
例外情况是你的服务器有多个CPU,那才能真正发挥多线程的优势,有多少个CPU就开多少线程.Top
19 楼chenyinxin(这里我最菜)回复于 2006-08-15 16:17:03 得分 0
是字符串的,指纹控件提供了方法对比的。
--------------
查看CPU和内存使用情况,如果用尽了,那只能升硬件
是否控件本身性能有问题?
最好能把数据都加载到内存!Top
20 楼dahaig(HarryPottor)回复于 2006-08-15 16:23:02 得分 10
多线程在单cpu机器上不能提高cpu效率,除非你是多cpu的机器
多线程才能发挥效果
解决办法,
建议将指纹数据压缩,到服务器再解压缩
Top
21 楼scow(怡红快绿之小橙子|和谐权是第4代人权)回复于 2006-08-15 16:35:28 得分 10
多线程带来的调度开销和速度方面能够提高的,哪个起主导作用,还是测试才知道,既然比单线程还慢,看来还是前者起了主导作用,不知改一下这个多线程的实现行不行,高手来解释解释Top
22 楼xiaolonghong()回复于 2006-08-15 20:56:02 得分 10
多线程的目标是充分利用硬件资源,如果cpu在运行时达到100%了,那再多线程不但没用,反而使运行更慢....
Top
23 楼myminimouse(坚决不用baidu)回复于 2006-08-15 21:25:34 得分 0
upTop




