【发布时间】:2017-11-29 10:21:03
【问题描述】:
为什么没有 Sleep(1) 就无法进入临界区?
type
TMyThread = class(TThread)
public
procedure Execute; override;
end;
var
T: TMyThread;
c: TRTLCriticalSection;
implementation
procedure TForm1.FormCreate(Sender: TObject);
begin
InitializeCriticalSection(c);
T := TMyThread.Create(false);
end;
procedure TMyThread.Execute;
begin
repeat
EnterCriticalSection(c);
Sleep(100);
LeaveCriticalSection(c);
sleep(1); // can't enter from another thread without it
until false;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
EnterCriticalSection(c);
Caption := 'entered';
LeaveCriticalSection(c);
end;
由于代码太多所以无法发布此文本文本文本文本文本。 哦,顺便说一句,如果该部分是由线程创建的,那么它工作正常。
【问题讨论】:
-
因为机会之窗太窄了。线程放弃了该部分,但随后立即回收它。
-
调用
Sleep(1)并没有做任何特别有趣的事情。您可能打算调用Sleep(0),而不是documented。另外,请更详细地编辑您的问题,而不是无用的占位符文本。 -
Sleep(0) 在我的情况下不起作用。只有 Sleep(>=1) 可以解决问题。无论如何,J...回答了我的问题。我不知道微软自 XP 以来改变了临界区的行为
-
微软很可能已经改变了自 XP 以来关键部分的未定义行为。如果您做出超出记录范围的假设,当您被咬时不要感到惊讶:(
-
@MartinJames:这不是未定义的行为。这是一个实现细节。尽管本身定义良好,但编写依赖它的代码很脆弱,并且随时可能中断,因此我同意您评论的第二部分。
标签: multithreading winapi freepascal critical-section