求多线程存取记录的算法

sztony 2004-09-01 09:40:43
1:
一文本文件,里面有几千条记录,为了加快存取,我采用多线程,
我采用的办法是,假如我用8个线程来读,则把该文件分成8段,每个线程读它分配的段,
每段的记录数量是文本文件的总记录数量除以线程数量,
但问题是:由于有误差,结果,总会漏掉一些记录,线程越多,漏的数量越多,
哪位高手有什么办法解决?

2:多个线程序如何安全地写同一个变量,好象老会出错,不知道哪位有什么高招?
...全文
195 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
sztony 2004-12-03
  • 打赏
  • 举报
回复
1:合适地采用多线程还是可以提高效率的.

2:当然这段代码还可以重构,比如把循环那段写成一个过程再调用,
这样就可免掉后面的处理剩余EMAIL的代码,但我不想玩了.
sztony 2004-12-03
  • 打赏
  • 举报
回复
好久没来了,今天看看,代码太长,只选取部分核心段代码.
程序是从EMAIL地址表中(.TXT),取得EMAIL地址,然后发送,通过一个公共变量计数,

基本原理是把地址表分成N段(用户可自定义),每一个线程处理对应的断,如果邮件数量不能被线程数整除,则由某一线程负责剩余数量处理,

采用临界方法,处理公共变量.

procedure mysendmail.Execute;
var
count_mail,tcount,i,j,Srecno,Erecno: integer; //count_mail;计算EMAIL控制变量,
tomail:string;
begin
tcount := 0; //发送EMAIL总数量
Srecno := Aqty_per_thread * Athreadcode; //每段线程读取的起始行
Erecno := Aqty_per_thread * (Athreadcode + 1)- 1; //每段线程读取的结束行
OnTerminate := transactionform.nextfile;
try
//=======================================================
// Starting send email
//=======================================================
for count_mail := Srecno to Erecno do
begin
tomail := trim(transactionform.lstbmaillist.Items[count_mail]);
transactionform.Memo1.Lines.Add(inttostr(count_mail)+' 正在发送到: '+
tomail +' /'+datetimetostr(now)+' 线程 : '+inttostr(Athreadcode));
transactionform.idmessage1[Athreadcode].Recipients.EMailAddresses := tomail;
transactionform.idsmtp1[Athreadcode].Send(transactionform.idmessage1[Athreadcode]);
inc(counters[Athreadcode]);
tcount := 0;
for i := 0 to threadnumber - 1 do
begin
tcount := tcount + counters[i];
end;
entercriticalsection(cs); //锁定变量
transactionform.lbpg.Caption := '已经完成: '+inttostr(tcount) ;
leavecriticalsection(cs); //释放锁定
end;

//=======================================================
// 发送剩余的EMAIL;
//=======================================================
Srecno := leaveSrec;
Erecno := totalqty - 1;
if Athreadcode = threadnumber - 1 then
begin
for count_mail := Srecno to Erecno do
begin
tomail := trim(transactionform.lstbmaillist.Items[count_mail]);
transactionform.Memo1.Lines.Add(inttostr(count_mail)+' 正在发送到: '+
tomail +' /'+datetimetostr(now)+' 线程 : '+inttostr(Athreadcode));
transactionform.idmessage1[Athreadcode].Recipients.EMailAddresses := tomail;
transactionform.idsmtp1[Athreadcode].Send(transactionform.idmessage1[Athreadcode]);
inc(counters[Athreadcode]);
tcount := 0;
for i := 0 to threadnumber - 1 do
begin
tcount := tcount + counters[i];
end;
entercriticalsection(cs);
transactionform.lbpg.Caption := '已经完成: '+inttostr(tcount) ;
leavecriticalsection(cs);
end;
end;

transactionform.Memo1.Lines.Add('线程 '+inttostr(Athreadcode)+' 完成任务 '+ inttostr(counters[Athreadcode])+' /'+datetimetostr(now));
isfinished[Athreadcode] := true;
except
transactionform.Memo1.Lines.Add('线程 '+inttostr(Athreadcode)+' 异常终止 ' +' /'+datetimetostr(now));
isfinished[Athreadcode] := true;
exit;
end;
end;
肥仔胧 2004-11-15
  • 打赏
  • 举报
回复
学习
cjf1009 2004-11-15
  • 打赏
  • 举报
回复
我觉得用多线程也提高不了效率,不如不用。
beyondtkl 2004-11-15
  • 打赏
  • 举报
回复
嗯 1你是怎么摆平的?

2嘛 多个线程同时写一个冬冬 当然会有问题
可能出现脏数据 或者 自己的数据被改写。。
就需要进行线程同步的处理。。方法很多 包括关键代码 信号量 事件 等。。。
chinaandys 2004-11-15
  • 打赏
  • 举报
回复
把代码贴出来看看

suizhou888@163.com
east_asp 2004-11-11
  • 打赏
  • 举报
回复
总结一下原因吗
sztony 2004-09-02
  • 打赏
  • 举报
回复
自己搞定了.
wofan 2004-09-01
  • 打赏
  • 举报
回复
把代码贴出来看看

16,748

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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