delphi 多线程 单步调试 诡异现象 无法挂起
一次偶然的开发环境中发现了这个现象,记录下来后自己写了一个demo。
问题描述: 主线程和子线程,在主线程中下一个断点,单步调试,发现子线程自身挂起后,在没有被主线程唤醒的情况下,
单步调试时,子线程莫名奇妙的苏醒了~~ 求高手解释!
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
MThread = class(TThread)
procedure Execute; override;
end;
var
Form1: TForm1;
_MarkCount : integer;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
LMyThreaed : MThread;
I : integer;
begin
_MarkCount := 0;
LMyThreaed := MThread.create(True);
for I := 0 to 100 -1 do
begin
sleep(5);
sleep(5);
sleep(5);
sleep(5);
sleep(5);
sleep(5);
sleep(5);
LMyThreaed.Resume;
sleep(5);
sleep(5);
//LMyThreaed.suspend;
sleep(5);
sleep(5);
sleep(5);
end;
end;
procedure MThread.Execute;
var
outputstr : string;
begin
while True do
begin
//打一个log
inc(_MarkCount);
outputstr := '|-----Excute Mark: ' + IntToStr(_MarkCount) + ' -----|';
outputdebugstring(Pchar(outputstr));
sleep(1);
sleep(1);
sleep(1);
sleep(1);
sleep(1);
sleep(1);
suspend;
end;
end;
end.
开发环境:delphi 2006,操作系统:windows 2003
现在来描述一下出现的问题:
当启动程序后,点击button后,在event log中看到100条 log信息,和主线程的循环中唤醒线程的次数一样。---正常
当在主线程的循环中下一个断点(红色代码处),当点击button断在断点处后,然后进行单步调试,执行“ LMyThreaed.Resume;”后,主线程唤醒子线程,然后子线程开始运行,运行到suspend之后,挂起,当主线程继续单步运行一步,发现子线程居然被唤醒了,但主线程并没有执行到唤醒子线程的那一行代码。---异常
我先抛砖引玉分析一下我的看法: 调试是以进程为单元进行调试,当程序断在主线程的断点时,delphi 2006 将挂起 整个进程( 包括进程中的所有线程 ),被挂起的同时会保存一些线程状态,当在主线程中继续单步调试到唤醒子线程时,子线程被唤醒,主线程继续单步执行一步,在这一步的时间内子线程可能执行了很多步,主线程继续一步一步的调试,子线程运行“suspend”挂起自己。 继续单步一步,此时子线程本应该是挂起状态,但在单步一步的时候,可能由于delphi 2006 保存的线程的状态中,子线程是非挂起状态,所以delphi 2006 将子线程唤醒,此时主线程还没有执行到下一次循环的唤醒子线程那一步。
本人能力有限,可能上面说的有些不对,不要乱喷~~只是想知道为什么会出现这种现象,希望得到高手详细的解释一下。
分不多,全部积蓄~将就一下吧~
[解决办法]
换成 TEvent吧,简单易用, resume和suspend已经被废弃了。
[解决办法]
该回复于2012-01-03 16:56:26被版主删除