简单多线程怎么老是出错,请高手指点(帖代码)(100分)

  • 主题发起人 主题发起人 abencat
  • 开始时间 开始时间
A

abencat

Unregistered / Unconfirmed
GUEST, unregistred user!
---窗体
object Form1: TForm1
Left = 212
Top = 46
Width = 432
Height = 694
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Button2: TButton
Left = 327
Top = 40
Width = 75
Height = 25
Caption = '停止'
TabOrder = 0
end
object Button3: TButton
Left = 324
Top = 7
Width = 75
Height = 25
Caption = '开始'
TabOrder = 1
OnClick = Button3Click
end
object StringGrid1: TStringGrid
Left = 0
Top = 0
Width = 304
Height = 667
Align = alLeft
RowCount = 100
TabOrder = 2
end
object Edt_N: TSpinEdit
Left = 332
Top = 78
Width = 68
Height = 22
MaxValue = 0
MinValue = 0
TabOrder = 3
Value = 10
end
end
---代码
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, Grids, Spin;
type
TForm1 = class(TForm)
Button2: TButton;
Button3: TButton;
StringGrid1: TStringGrid;
Edt_N: TSpinEdit;
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure TestOK(sender: TObject);
end;

var
Form1: TForm1;
implementation
uses BounceThread;
var
P: array of TBounceThread;
{$R *.DFM}
procedure TForm1.Button3Click(Sender: TObject);
var
i:integer;
begin
SetLength(P,Edt_N.Value);
InitializeCriticalSection(CS);
//初始化临界区
for i:=0 to Edt_N.Value-1do
begin
P:=TBounceThread.Create(true);
P.Resume;
end;
end;
procedure TForm1.TestOK(sender: TObject);
begin

end;

end.

---

unit BounceThread;
interface
uses
Windows, Messages, SysUtils, WinProcs,Classes,Graphics,ExtCtrls,unit1;
var
CS: TRTLCriticalSection;
//定义全局临界区
type
TbounceThread = class(TThread)
private
iCur:integer;
procedure MoveShape();
protected
procedure Execute;override;
public
constructor Create(Suspended:Boolean);
end;

implementation
constructor TBounceThread.Create(Suspended:Boolean);
begin
inherited Create(Suspended);
FreeOnTerminate:=True;
end;
procedure TbounceThread.MoveShape();
var
i:integer;
begin
Form1.StringGrid1.Cells[0,iCur]:='OK';
for i:=0 to 10do
begin
Form1.StringGrid1.Cells[2,iCur]:=inttostr(i);
sleep(300);
end;
end;

procedure TbounceThread.Execute;
var
i:integer;
begin
for i:=0 to Form1.StringGrid1.RowCount-1do
begin
if Form1.StringGrid1.Cells[0,i]='' then
begin
//开始运行一个过程 做事情
iCur:=i;
MoveShape;
//synchronize(MoveShape);
end;
//结束线程
if i=Form1.StringGrid1.RowCount-1 then
Terminate ;
end;
end;

end.
 
出错问题是
当有10个线程开始工作时候 有时候是会少1~2个 有时候是出错
请高手指点一下
 
把 Form1.StringGrid1.Cells[0,i]='' 作为参数递进线程应该好点
 
procedure TbounceThread.Execute;
var
i:integer;
begin
for i:=0 to Form1.StringGrid1.RowCount-1do
begin
if Form1.StringGrid1.Cells[0,i]='' then
begin
//开始运行一个过程 做事情
iCur:=i;
MoveShape;
//synchronize(MoveShape);
end;
//结束线程
if i=Form1.StringGrid1.RowCount-1 then
Terminate ;
end;
end;

最好写成这样:
procedure TbounceThread.Execute;
begin
synchronize(dosomething);
end;
procedure TbounceThread.dosomething;
var
i:integer;
begin
for i:=0 to Form1.StringGrid1.RowCount-1do
begin
if Form1.StringGrid1.Cells[0,i]='' then
begin
//开始运行一个过程 做事情
iCur:=i;
MoveShape;
//synchronize(MoveShape);
end;
//结束线程
if i=Form1.StringGrid1.RowCount-1 then
Terminate ;
end;
end;
你试一下。
 
换成你的写法 运行就是死机
 
procedure TbounceThread.Execute;
var
i:integer;
begin
[red] EnterCriticalSection(CS);
try[/red]
for i:=0 to Form1.StringGrid1.RowCount-1do
begin
if Form1.StringGrid1.Cells[0,i]='' then
begin
//开始运行一个过程 做事情
iCur:=i;
MoveShape;
//synchronize(MoveShape);
end;
//结束线程
if i=Form1.StringGrid1.RowCount-1 then
Terminate ;
end;
[red] finally
LeaveCriticalSection(CS);
end;
[/red]
end;
 
zqw0117,
你的方法是不错 可是我要的是同步操作
你的是一不一步运行的
 
比如:有89个文件需要下载
我就用10个线程同时下载10个文件,每个线呈下载完一个后去找下一个需要下载的文件继续下载
 
有没有高手指点一下呀
 
指点指点呀
 
自己 顶~~~~~~~~~~~~~~~~~~~~~~~
 
我不知道,你为什么把同步注释掉了,而且声明临界区也没有用。我建议procedure TbounceThread.MoveShape();
var
i:integer;
begin
Form1.StringGrid1.Cells[0,iCur]:='OK';
for i:=0 to 10do
begin
Form1.StringGrid1.Cells[2,iCur]:=inttostr(i);
sleep(300);
end;
end;
修改成:如果不用同步的话
procedure TbounceThread.MoveShape();
var
i:integer;
begin
Form1.StringGrid1.Cells[0,iCur]:='OK';
for i:=0 to 10do
begin
EnterCriticalSection(CS);
try
Form1.StringGrid1.Cells[2,iCur]:=inttostr(i);
finally
LeaveCriticalSection(CS);

end;
sleep(300);
end;
end;
 
请问InitializeCriticalSection(CS);
//初始化临界区在这有什么用,好像没有用到
 
是这里出了问题吧:
//结束线程
if i=Form1.StringGrid1.RowCount-1 then
Terminate ;
怎么可以Terminate 呢?
 
那使用什么结束呢
 
if i=Form1.StringGrid1.RowCount-1 then
Terminate ;
這句可以不用
 
不要也出错呀
 
出什麼錯?
出什麼錯?
 
不过又有一个新的问题,就是如果通过sql server2000函数取得服务器上的硬件信息呢(比如:硬盘号、cpu信息、网卡等)
 

Similar threads

I
回复
0
查看
684
import
I
I
回复
0
查看
621
import
I
I
回复
0
查看
696
import
I
后退
顶部