I have a function which accepts an action. The function obtains a semaphore lock (but for the purposes of the question could also be a monitor lock) and then calls the action.
A code reviewer has stated does not represent an effective way to implement thread-safety because it is prone to deadly embrace. Thread-safe code should be encapsulated but you break this by allowing a third-party to invoke an external action. (It's like raising an event inside a lock.)
Ignoring the encapsulation bit, is there any special case with calling actions from with a lock? My instinct is to say an action is no more likely to incur a deadlock than any other code but before i challenge that, is he right??
The problem with calling external code when lock is acquired is that you cannot guarantee anymore that your code is deadlock-safe.
The caller can do anything in the callback action.
Here is a few examples when action might perform 'dangerous':
Recursive call of a function. Deadlock is possible in that case.
Perform some long running operation. That might downgrade the others threads performance if they need the same synch object (monitor or semaphore).
I believe there are the other negative cases also possible.
The purpose of a monitor (or a semaphore) is to prevent simultaneous entering into the code section, which is definitely should not be run simultaneously. That is not the case for the callback action.
So, there is no good reason to call action within the lock.
I would suggest here instead to call the callback action either before the lock is acquired or after it is released.
Related
I know Synchronize must be used in the Execute procedure, but should it be used in Create and Destroy methods too, or is it safe to do whatever I want?
I know Synchronize must be used in the Execute procedure.
That is somewhat vague. You need to use Synchronize when you have code that must execute on the main thread. So the answer to whether or not you will need to use Synchronize depends crucially on what the code under consideration actually does. The question that you must ask yourself, and which is one that only you can answer, is do you have code that must run on the main thread?
As a general rule it would be considered prudent for you not to need to call Synchronize outside the Execute method. If you can find a way to avoid doing so then that would be wise. Remember that the ideal scenario with threads is that they never need to block with Synchronize if at all possible.
You might also wish to consider which thread executes the constructor and destructor.
The constructor Create runs in the thread that calls it. It does not run in the newly created thread. Therefore it is unlikely that you would need to use Synchronize there.
The destructor Destroy runs in the thread that calls it. Typically this is the thread that calls Free on the thread object. And usually that would be called from the same thread that originally created the thread. The common exception to that is a FreeOnTerminate thread which calls Free from the thread.
There is a need to use Synchronize() when the code is executing outside of the context of the main (GUI) thread of the application. Therefore the answer to your question depends on whether the constructor and destructor are called from that thread or not.
If you are unsure you can check that by comparing the result of the Windows API function GetCurrentThreadId() with the variable MainThreadID - if they equal the code executes in the context of the main thread.
Threads that have FreeOnTerminate set will have their destructor called from another thread context, so you would need to use Synchronize() or Queue(). Or you use the termination event the VCL already provides, I believe it is executed in the main thread, but check the documentation for details.
First of all, you don't want to call Synchronize() unnecessarily, because that simply defeats the purpose of using a thread. So the decision should be based on whether: (a) it's possible to encounter race conditions with shared data. (b) you'll be using VCL code which usually has to run on the main thread.
It's unlikely you would need to synchronise in the constructor because TThread instances are usually created from the main thread already. (The exception being if you're creating some TThread's from another child thread.)
NOTE: It won't cause any harm though because Synchronize() already checks if you're on the main thread and will call the synchronised method immediately if you are.
class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord; QueueEvent: Boolean = False);
var
SyncProc: TSyncProc;
SyncProcPtr: PSyncProc;
begin
if GetCurrentThreadID = MainThreadID then
ASyncRec.FMethod
As for the destructor there are 3 usage patterns:
The TThread instances destroys itself.
Another thread (possibly the main thread) can WaitFor the instance to finish, then destroy it.
You can intercept the OnTerminate event. This is fired when the instance is finished, and you could then destroy it.
NOTE: The OnTerminate event will already be synchronised.
procedure TThread.DoTerminate;
begin
if Assigned(FOnTerminate) then Synchronize(CallOnTerminate);
end;
Given the above, the only time you might need to synchronise is if the thread self-destructs.
However, I'd advise that you rather avoid putting code into your destructor that might need to be synchronised. If you need some results of a calculation from your thread instance, OnTerminate is the more appropriate place to get this.
To add to what has been said in other answers...
You never need to use Synchronize at all. Synchronize may be useful, however, in the following circumstance:
In the context of your thread you need to execute code that touches objects that have affinity to the main thread.
You require your thread to block until that code has been executed.
Even in that case, there are other ways to achive the same goal, but Synchronize provides a convenient way to satisfy those two needs. If you need only one of those two items, there are better strategies available.
On topic #1, the obvious objects are user interface objects. These are objects that have thread affinity to the main thread simply by virtue of the fact that the main thread is continually reading and writing the properties of those objects (not the least because it needs to paint them to the screen, etc) and it does so at its own convenience. This means that your thread cannot safely access those components with a guarantee that the main thread will not also be accessing or modifying them at the same time. In order to prevent corruption, the thread has to pass the work to the main thread (since the main thread can only do one thing at a time and can't, obviously, interfere with itself). Synchronize simply places the work onto the main thread's queue and waits until the main thread gets around to completing it before returning.
This gets to point #2. Do you need to (or, equally, can you afford to) wait around until the main thread finishes the work? There are three cases and two options.
Yes, you can or must wait. (Synchronize is a good fit)
No, you cannot wait. (Synchronize is not a good fit)
Don't care. (Synchronize is easy, so it's a sensible option)
If you are simply updating a status display that will soon be overwritten anyway and your thread has more pressing issues, then it's probably sensible to just post a message to the main thread and carry on doing things, for example. If your thread is just waiting around doing nothing, mostly, and it's not worth the time to code anything more sophisticated, then Synchronize is just fine, and it can be replaced with something better if needs dictate so in the future.
As others have said, it really depends on what you are doing. The more important question, I think, at least conceptually, is to sort out when you need to worry about concurrency and when you don't. Any time you have more than one thread that requires access to a single resource you need to use some sort of mechanism to coordinate that access to avoid the threads crashing into each other. Synchronize is one of those methods, but it not the least nor the last of them.
I understand (somewhat) the features of the jdk 5 ReentrantLock here
But why we would want a 're-entrant' lock? i.e if a Thread already has the lock on an Object, why would it need to acquire it again?
Consider this theoretical example: You are using a lock to protect some back-end data while updating some items in a list box in your GUI. You loop through and modify the items. While doing so, the list box fires an event (perhaps a Selection Changed event or something) for which you have a handler registered. This handler also locks the same lock in order to process the new item. If the lock is not recursive, this thread would deadlock on the second attempt to acquire the lock.
Reentrant locks are useful in cases where a resource cannot tolerate all forms of arbitrarily-timed accesses, but can tolerate certain patterns of access which can occur in nested execution contexts. In many cases their usage is unaesthetic and sloppy, but it may be easier to arrange things so that a reentrant lock can be guaranteed to work than it would be to arrange things so as to make one unnecessary.
Note that while many languages default to making locks reentrant, that is not necessarily a good thing. If code acquires a lock and then other code in that thread tries to acquire a token for that same lock, it's clear that that having the second request wait until lock has been released isn't going to be very productive. That does not imply, however, that the second request should allow access to the lock. In many cases a proper course of action would be for the second request to throw an immediate exception (access shouldn't be granted until the lock is released, and that can't happen until either the request is granted (which shouldn't happen) or the code exits some other way (an exception being the most natural choice). Such a situation would apply if the a method which was modifying a lock-guarded data structure called some outside code which wasn't expected to use the data structure while the data structure was in an inconsistent state. If the code unexpectedly does try to use the data structure, having it fail immediately with an exception may be better than having it wait forever for a lock it's never going to get, or blithely proceed into a lock and access invalid data.
There are many cases where code will call nested routines at times when a guarded resource satisfies some but not all of its invariants, and where the outside code may expect the nested routines to make some kinds of changes to it but not others. In such cases, reentrant locks may be appropriate, but care is required to ensure that code doesn't do things it shouldn't. One advantage of reentrant locks is that if code which makes nested calls with the lock held sets flags to indicate its promises/requirements, and code which acquires the lock tests those flags on entry, one can guarantee that the flags will only be manipulated in predictable sequences. Such a thing would not be possible if two different threads were trying to use the resource simultaneously.
How can i make a callback function thread safe. This function will be called by different threads to update UI. This callback function will have an HWND parameter which will be filled by the caller. The function will use this HWND parameter to update GUI. HWND will be different for different calls.
Please tell me how can i make this callback thread safe.
Regards.
John
Please tell me how can i make this callback thread safe.
If there's no state required by the callback function, it's already threadsafe, unless the GUI functions themselves are not threadsafe (see the 2nd half of this answer).
If there is state required, include a mutex in that state, and lock the mutex during any read/write accesses.
There are more complex lock paradigms (e.g. multiple-reader/single-writer locks) but you probably won't need that for a GUI.
The other issue for GUIs (true for Java Swing; I can't remember whether this is true for win32 or not) is that GUI operations should usually be performed in one particular thread. In win32, that's the reason for posting and sending messages (which are processed by one thread).
If you wanted to use this approach, anytime you want to perform a GUI operation, you should check whether you are in the GUI thread (can't remember how to do that in win32), or perform a PostMessage() call to kick off particular GUI operations.
I have a native Visual C++ COM object and I need to make it completely thread-safe to be able to legally mark it as "free-threaded" in th system registry. Specifically I need to make sure that no more than one thread ever accesses any member variable of the object simultaneously.
The catch is I'm almost sure that no sane consumer of my COM object will ever try to simultaneously use the object from more than one thread. So I want the solution as simple as possible as long as it meets the requirement above.
Here's what I came up with. I add a mutex or critical section as a member variable of the object. Every COM-exposed method will acquire the mutex/section at the beginning and release before returning control.
I understand that this solution doesn't provide fine-grained access and this might slow execution down, but since I suppose simultaneous access will not really occur I don't care of this.
Will this solution suffice? Is there a simpler solution?
This solution should work, but I'd recommend mutexes over critical sections as they handle time-outs, which provide some level of fall back in case of deadlock. You also want to be very careful that a function locking a mutex does not call another function that has already locked the same mutex in the same thread. This shouldn't be a problem for your COM interface, so long as you don't add extra functionality on top of your mutex to the interface. You could hit issues if the COM includes call backs.
If you are certain that actual concurrent access is not going to happen in practice, then mutexing the entire execution is not an unreasonable approach.
What is the difference between the concepts of "Code Re-entrancy" and "Thread Safety"? As per the link mentioned below, a piece of code can be either of them, both of them or neither of them.
Reentrant and Thread safe code
I was not able to understand the explaination clearly. Help would be appreciated.
Re-entrant code has no state in a single point. You can call the code while something is executing in the code. If the code uses global state, one call can conceivably overwrite the global state, breaking the computation in the other call.
Thread safe code is code with no race conditions or other concurrency issues. A race condition is where the order in which two threads do something affects the computation. A typical concurrency issue is where a change to a shared data structure can be partially completed and left in an inconsistent state. In order to avoid this, you have to use concurrency control mechanisms such as semaphores of mutexes to ensure that nothing else can access the data structure until the operation is completed.
For example, a piece of code can be non re-entrant but thread-safe if it is guarded externally by a mutex but still has a global data structure where the state must be consistent for the entire duration of the call. In this case, the same thread could initiate a call-back into the procedure while still protected by an external coarse-grained mutex. If the call-back occured from within the non re-entrant procedure the call could leave the data structure in a state that could break the computation from the caller's point of view.
A piece of code can be re-entrant but non thread-safe if it can make a non-atomic change to a shared (and sharable) data structure that could be interrupted in the middle of the update leaving the data structure in an incosistent state. In this case another thread accessing the data structure could be affected by the half-changed data structure and either crash or perform an operation that corrupts the data.
That article says:
"a function can be either reentrant, thread-safe, both, or neither."
It also says:
"Non-reentrant functions are thread-unsafe".
I can see how this may cause a muddle. They mean that standard functions documented as not required to be re-entrant are also not required to be thread-safe, which is true of the POSIX libraries iirc (and POSIX declares it to be true of the ANSI/ISO libraries too, ISO having no concept of threads and hence no concept of thread-safety). In other words, "if a function says it is non-reentrant, then it is saying it's thread-unsafe too". That's not a logical necessity, it's just a convention.
Here's some pseudo-code which is thread-safe (well, there's plenty of opportunity for callbacks to create deadlocks due to locking inversion, but let's assume the documentation contains sufficient information for users to avoid that) but not re-entrant. It is supposed to increment the global counter, and perform the callback:
take_global_lock();
int i = get_global_counter();
do_callback(i);
set_global_counter(i+1);
release_global_lock();
If the callback calls this routine again, resulting in another callback, then both levels of callback will get the same parameter (which might be OK, depending on the API), but the counter will only be incremented once (which is almost certainly not the API you want, so it would have to be banned).
That's assuming the lock is recursive, of course. If the lock is non-recursive, then of course the code is non-reentrant anyway, since taking the lock the second time won't work.
Here's some pseudo-code which is "weakly re-entrant" but not thread-safe:
int i = get_global_counter();
do_callback(i);
set_global_counter(get_global_counter()+1);
Now it's fine to call the function from the callback, but it's not safe to call the function concurrently from different threads. It's also not safe to call it from a signal handler, because re-entrancy from a signal handler could likewise break the count if the signal happened to occur at the right time. So the code is non-re-entrant by the proper definition.
Here's some code which arguably is fully re-entrant (except I think the standard distinguishes between reentrant and 'non-interruptible by signals', and I'm not sure where this falls), but still isn't thread-safe:
int i = get_global_counter();
do_callback(i);
disable_signals(); // and any other kind of interrupts on your system
set_global_counter(get_global_counter()+1);
restore_signal_state();
On a single-threaded app, this is fine, assuming that the OS supports disabling everything that needs to be disabled. It prevents re-entrancy from occurring at the critical point. Depending how signals are disabled, it may be safe to call from a signal handler, although in this particular example there's still the issue of the parameter passed to the callback being the same for separate calls. It can still go wrong multi-threaded, though.
In practice, non-thread-safe often implies non-re-entrant, since (informally) anything that can go wrong due to the thread being interrupted by the scheduler, and the function called again from another thread, can also go wrong if the thread is interrupted by a signal, and the function is called again from the signal handler. But then the "fix" to prevent signals (disabling them) is different from the "fix" to prevent concurrency (locks, usually). This is at best a rule of thumb.
Note that I've implied globals here, but exactly the same considerations would apply if the function took as a parameter a pointer to the counter and the lock. It's just that the various cases would be thread-unsafe or non-re-entrant when called with the same parameter, rather than when called at all.