开发者

Can I nest critical sections? Is TCriticalSection nestable?

I want to have two procedures which can call each ot开发者_开发技巧her, or be called from whatever threads are running, but only have one running at a time. How can I do this? Will this work correctly?

var
  cs: TCriticalSection;

procedure a;
begin
  cs.Acquire;
  try
    // Execute single threaded here. 
  finally
    cs.Release;
  end;
end;

procedure b;
begin
  cs.Acquire;
  try
    // Execute single threaded here. Maybe with calls to procedure a.
  finally
    cs.Release;
  end;
end;


Yes, that will work. Procedure A can call B and vice versa within the same thread and while Thread A is using procedure A or B, Thread B has to wait when it wants to use those procedures.

See the MSDN documentation about Critical Sections: http://msdn.microsoft.com/en-us/library/ms682530%28VS.85%29.aspx

Critical sections can be nested, but for every call to Acquire you must have a call to Release. Because you have your Release call in a try .. finally clause you ensure that this happens, so your code is fine.


While it is possible on Windows to acquire a critical section multiple times, it is not possible on all platforms, some of them will block on the attempt to re-acquire a synchronization object.

There is not really a need to allow for "nesting" here. If you design your classes properly, in a way that the public interface acquires and releases the critical section, and the implementation methods don't, and if you make sure that implementation methods never call interface methods, then you don't need that particular feature.

See also the Stack Overflow question "Recursive Lock (Mutex) vs Non-Recursive Lock (Mutex)" for some details on the bad sides of recursive mutex / critical section acquisition.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜