不知道各位调试的时候有没有发现:当执行 for i := 1 to MaxSize do这句时,i是从maxsize 到 1逐渐递减循环的,而且当执行 GlobalArray[MaxSize] := GetNextNumber时往往得出的是GlobalArray[1]的值,很奇怪,应该递增才对,why?
for i := 1 to MaxSize do 是递增的
to C_Sharp:这个我当然知道,但调试的时候为什么显示是递减呢? to chechy:thank you,数字是随机的,但你有没有发现:不知道各位调试的时候有没有发现:当执行 for i := 1 to MaxSize do这句时,i是从maxsize 到 1逐渐递减循环的,而且当执行 GlobalArray[MaxSize] := GetNextNumber时往往得出的是GlobalArray[1]的值,很奇怪,应该递增才对,why?
欢迎大家都来调试,源代码如下: unit Main;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type TMainForm = class(TForm) Button1: TButton; ListBox1: TListBox; procedure Button1Click(Sender: TObject); private procedure ThreadsDone(Sender: TObject); end; TFooThread = class(TThread) protected procedure Execute; override; end;var MainForm: TMainForm;implementation{$R *.DFM}const MaxSize = 128;var NextNumber: Integer = 0; DoneFlags: Integer = 0; GlobalArray: array[1..MaxSize] of Integer;function GetNextNumber: Integer; begin Result := NextNumber; // return global var Inc(NextNumber); // inc global var end;procedure TFooThread.Execute; var i: Integer; begin OnTerminate := MainForm.ThreadsDone; for i := 1 to MaxSize do begin GlobalArray[i] := GetNextNumber; // set array element Sleep(5); // let thread intertwine end; end;procedure TMainForm.ThreadsDone(Sender: TObject); var i: Integer; begin Inc(DoneFlags); if DoneFlags = 2 then // make sure both threads finished for i := 1 to MaxSize do { fill listbox with array contents } Listbox1.Items.Add(IntToStr(GlobalArray[i])); end;procedure TMainForm.Button1Click(Sender: TObject); begin TFooThread.Create(False); // create threads TFooThread.Create(False); end;end.只需添加一个按钮,列表框
to chechy:谢谢你的关注,不过我问你一句,你调试到for i := 1 to MaxSize do这句没有? 根据你的回答,你肯定没有! 我调试过n遍,所以我才敢下结论, 如果大家知道来由的话,我觉得这个发现很有价值! 大家以后肯定会碰到此类问题!
是怎么加的呢?Inc(NextNumber)按理说只应该加1呀,
NextNumber怎么一下从0变为255呢
这是关键所在
请注意这个程序同时开启了两个线程,两个线程没有信号量锁定,所以同时在向NextNumber申请数字,加之又有Sleep的时间,导致两个线程轮流取数字,显示的第二个线程的数据,它当然就是1,3,5...,第一个线程应该是0,2,4...。
to chechy:thank you,数字是随机的,但你有没有发现:不知道各位调试的时候有没有发现:当执行 for i := 1 to MaxSize do这句时,i是从maxsize 到 1逐渐递减循环的,而且当执行 GlobalArray[MaxSize] := GetNextNumber时往往得出的是GlobalArray[1]的值,很奇怪,应该递增才对,why?
这样你才有可能发现I值不是递增。实际上对于一个线程来说I值一定是递增的。
这两个线程交替没有任何规律,完全随机,所以你每次调试都不太会得到相同结果。
unit Main;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;type
TMainForm = class(TForm)
Button1: TButton;
ListBox1: TListBox;
procedure Button1Click(Sender: TObject);
private
procedure ThreadsDone(Sender: TObject);
end; TFooThread = class(TThread)
protected
procedure Execute; override;
end;var
MainForm: TMainForm;implementation{$R *.DFM}const
MaxSize = 128;var
NextNumber: Integer = 0;
DoneFlags: Integer = 0;
GlobalArray: array[1..MaxSize] of Integer;function GetNextNumber: Integer;
begin
Result := NextNumber; // return global var
Inc(NextNumber); // inc global var
end;procedure TFooThread.Execute;
var
i: Integer;
begin
OnTerminate := MainForm.ThreadsDone;
for i := 1 to MaxSize do
begin
GlobalArray[i] := GetNextNumber; // set array element
Sleep(5); // let thread intertwine
end;
end;procedure TMainForm.ThreadsDone(Sender: TObject);
var
i: Integer;
begin
Inc(DoneFlags);
if DoneFlags = 2 then // make sure both threads finished
for i := 1 to MaxSize do
{ fill listbox with array contents }
Listbox1.Items.Add(IntToStr(GlobalArray[i]));
end;procedure TMainForm.Button1Click(Sender: TObject);
begin
TFooThread.Create(False); // create threads
TFooThread.Create(False);
end;end.只需添加一个按钮,列表框
根据你的回答,你肯定没有!
我调试过n遍,所以我才敢下结论,
如果大家知道来由的话,我觉得这个发现很有价值!
大家以后肯定会碰到此类问题!
你有没有监视i值的变化,是不是递减?
“调试线程本来就比较困难,要知道你设的断点有可能是A线程断的,也有可能是B线程断的。
这样你才有可能发现I值不是递增。实际上对于一个线程来说I值一定是递增的。
这两个线程交替没有任何规律,完全随机,所以你每次调试都不太会得到相同结果。 ”
广州