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.
精彩评论