Unable to enter critical section
Asked Answered
N

1

5

Why is it imposible to enter critical section without 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; 

Can't post this because of too much code so text text text text text. Oh by the way if the section is created by the thread then it is working fine.

Nuris answered 29/11, 2017 at 10:21 Comment(5)
Because the window of opportunity is too narrow. The thread gives up the section, but then immediately reclaims it.Quinte
Calling Sleep(1) doesn't do anything particularly interesting. You probably meant to call Sleep(0) instead, as documented. Also, please edit your question with more detail, instead of the useless placeholder text.Danaedanaher
Sleep(0) didn't work in my case. Only Sleep(>=1) does the trick. Anyway J... answered my question. I didn't know that microsoft changed the behaviour of the critical sections since XPNuris
Microsoft may well have changed the undefined behaviour of the critical sections since XP. If you make assumptions beyond that documented, don't be surprised when you get bitten:(Experimental
@MartinJames: This isn't undefined behavior. It's an implementation detail. Though well defined in and of itself, writing code that relies on it is brittle, and can break at any time, so I agree with the second part of your comment.Danaedanaher
A
8

There is no guarantee that threads acquire a critical section on a FIFO basis (MSDN). If your current thread always re-acquires the critical section a few uops after releasing it then chances are that any other waiting threads will likely never wake in time to find it available themselves.

If you want better control of lock sequencing there are other synchronization objects you can use. Events or a queue might be suitable but we don't really know what you are trying to achieve.

Atrophy answered 29/11, 2017 at 10:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.