多线程的问题,请教高手,难度比较大!!急!急!(300分)

  • 主题发起人 主题发起人 hpretty
  • 开始时间 开始时间
H

hpretty

Unregistered / Unconfirmed
GUEST, unregistred user!
一个线程在硬盘上找文件,找到后就将它删除,(由于硬盘大120G的,有12个,
找一次要4分钟)找一次,两次没问题,多次就不行了,就报指针操作错误。请问这能的问题是什么
我是用CreateThread来做的,是不是这个函数要注意点什么?
 
来自delphi4编程技术内幕
delphi4中的vcl不是线程安全的。
(注意,如果你试着从线程中调用VCL的可视元素,你的系统肯定是迟早要崩溃的,
但是,崩溃也许不会立即发生。)
为了避免出现这种情况,只有采取一种叫做TThread对象的折衷方法。
1。它提供了Synchronize函数,是你能够从一个线程调用vcl.
2。它提供了线程局部存储器(thread locaol storage)的一个替代物,使运行速度可以快10倍。
作为一般性的规则,你能在一个线程莉调用vcl的唯一方式就是适用synchronize。
关键是几乎大部分的vcl不是线程安全的,所以当程序在一个线程中的时候,你不能访问vcl。
周期,就是它的原因。调用synchronize实际上就是暂时结束你的线程,并使它成为你的应用程序
的主线程的一部分。这段时间内,你可以调用vcl。在你已完成对vcl的访问的时候,就应该中断程
序中同步完成部分的代码。
所以你应该试着用TThread来解决你的问题。
 
我有一个多线的文件查找程序
你的EMAIL是多少?我发给你
 
zhangzhaofei@163.com
 
这是我写的代码,是把硬盘上的文件进行分类的代码,这是大部分的代码, 你自己用来
修改就可以用了,应该不难吧。
unit PubUnit;
interface
uses
Classes,Messages,ComCtrls,SysUtils,Forms;

const
CM_THREADDONE=WM_USER+$2;
type
TFilterList=array[1..4]of TStringList;
TAllTypeList=array[1..4]of TListView;
function GetLocaPath:string;
implementation
function GetLocaPath:string;
begin
Result:=Extractfiledir(Application.exename);
if length(Result)=3 then
Delete(Result,3,3);
end;

end.

unit FindFileThread;
interface
uses
Windows,Classes,ComCtrls,SysUtils,PubUnit,Grids,StdCtrls;
type
TSanFile= class(TThread)
private
{ Private declarations }
FDir:TStrings;
FPath:string;
FFilters:TFilterList;
//查找文件的后缀列表
//文件添加的字符表
FList:TAllTypeList;
//传导进的列表控件
FFileInfo:TStringGrid;
FileS:array[1..4]of integer;
FMemo:TMemo;
proceduredo
San(const Path:string);
// procedure ScanInf(const FileName:string);
procedure AddInf(const FileName:string;size:integer);
procedure AddInfo(j,i,count,size:integer);
procedure AddLog;
protected
procedure Execute;
override;
public
constructor CreatFindFile(CDir:TStrings;
Filters:TFilterList;
List:TAllTypeList;
FileInfo:TStringGrid;
Memo:TMemo);
destructor Destroy;override;
end;

implementation
uses SanLogUnit;
{ TFindFile }
constructor TSanFile.CreatFindFile(CDir:TStrings;filters:TFilterList;
List:TAllTypeList;FileInfo:TStringGrid;Memo:TMemo);
var
i:integer;
begin
inherited Create(true);
Freeonterminate:=true;
FDir:=CDir;
FFilters:=Filters;
FList:=List;
FFileInfo:=FileInfo;
FMemo:=Memo;
for i:=1 to 4do
FileS:=0;
Resume;
end;

procedure TSanFile.AddLog;
begin
FMemo.Lines.Strings[2]:=' '+FPath;
end;

procedure TSanFile.AddInfo(j,i,count,size:integer);
begin
FFileInfo.Cells[j,i]:=Format('%d 个文件',[count]);
FFileInfo.Cells[j+1,i]:=Format('共计:%d 字节',[size]);
end;

procedure TSanFile.Execute;
const
TABS=#13+#10;
var
i:integer;
bTime,eTime:TDateTime;
begin
bTime:=Now;
Synchronize(AddLog);
for i:=1 to FDir.Countdo
do
San(FDir.Strings[i-1]);
eTime:=Now;
FPath:=' 扫描结束...'+TABS+' 开始时间为:'+DateTimeToStr(bTime)+TABS+
' 结束时间为:'+DateTimeToStr(eTime)+TABS+
' 共计用时为:'+TimeToStr(eTime-bTime);
Synchronize(AddLog);

end;

procedure TSanFile.AddInf(const FileName:string;Size:integer);
var
i,j:integer;
listdata:TListItem;
begin
for j:=1 to 4do
begin
i:=FFilters[j].IndexOf(UpperCase(ExtractFileExt(FileName)));
if i>=0 then
break;
end;
if i<0 then
exit;
listdata:=FList[j].Items.Add;
FileS[j]:=FileS[j]+size;
AddInfo(1,j,FList[j].Items.Count,FileS[j]);
with listdatado
begin
listdata.ImageIndex:=j-1;
Caption:='';
Subitems.Add(ExtractFileName(FileName));//添加文件名
Subitems.Add(FormatFloat('#,###" 字节"',Size));
//添加文件大小
case j of
1:Subitems.Add('音乐文件');
2:Subitems.Add('图片文件');
3:Subitems.Add('视频文件');
4:Subitems.Add('其他文件');
end;
Subitems.Add(FileName);
//添加文件路径
end;
end;

procedure TSanFile.DoSan(const Path:string);
var
FSR:TSearchRec;
begin
if FindFirst(Path+'/*.*',faAnyFile,FSR)=0 then
try
FPath:='当前扫描路径:'+Path+'/';
Synchronize(AddLog);
FindNext(FSR);
while (FindNext(FSR)=0) and (not Terminated)do
begin
//AddLog;
if ((FSR.Attr and faDirectory)<>faDirectory) then
//如果是文件
AddInf(Path+'/'+FSR.Name,FSR.Size)
else
//如果是文件夹
do
San(Path+'/'+FSR.Name);
end;
finally
FindClose(FSR);
end;
end;

destructor TSanFile.Destroy;
begin
PostMessage(ScanLog.Handle,CM_THREADDONE,0,0);
inherited Destroy;
end;

end.
 
把各类的文件信息显示到一个StringGrid里面,具体的各类文件显示到ListView里面
 
我的MSN是sunhuiNO1@hotmail.com
 
高难的,上。。。
 
你在线吗?
 
由于文件扫描的瓶颈是硬盘I/O,所以一个线程就够了,就不用互斥同步了
 
我联机了,是不是你写错了,sunhuiNO1@hotmail.com
 
bubble 你的MSN呢?
我的是ZHANGZHAOFEI@HOTMAILC.OM
 
呵呵,不错不错,
另外,我这里还有一个极好的线程查找的例子,算法界面都是上等,
老外编的,已经发了,查收吧。
msn我加你了,没有联机。
 
bubble,可不可以发份比我?
多谢了,smallsand@msn.com
 
能多跟你学习学习吗?张大侠,小弟才学线程不久,希望能和你多学习,请多指教!
 
多人接受答案了。
 
后退
顶部