Why does my program hang when I call Free on a thread? - multithreading

I dropped using FreeOnTerminate := true in favor of setting it explicitly to false, but now the code locks up every time I attempt to explicitly free the thread. I determined the lockup occurs at the Free statement.
For the last step of the thread process, I'm sending a message to a window handle I created in the main object to signal "finish." There I'm running a event, and then doing the free. Why does this happen?

I think that this is a typical multi-threading dead-lock.
When your thread sends the finish signal through sendmessage, the thread waits for the sendmessage to return before it will do anything else (e.g. the free procedure). At the same time, your main thread is waiting for the thread to free before finishing the event and processing the thread's sendmessage.
Have you tried to use postmessage instead which returns immediately and does not wait for result?

Related

Mechanism of join() in multithreading

I was studying about multi-threading and came across join().
As I understand right, using join() on the thread makes process wait until 'joined' thread terminates. For example, calling t1.join() in main will make main wait until the job in thread t1 is finished and t1 terminates.
I'm just curious that how the function join() make this possible - how does it make current thread 'blocked' inside the function? Does join() force execution of joined thread first so any other thread should wait until that thread terminates? Or, is there some way to communicate between two threads(the thread who called join() and the thread who is joined)?
I will be waiting for the answer. Thanks a lot!
To be able to join you need to be able to wait on some event. Then join looks like this:
function join(t : Thread)
// do this atomically
if already done
return
wait on termination event of t
end
Waiting can be done in one of two ways:
Looping and periodically checking if the event has happened (busy wait)
Letting the system reclaim the resources of the thread and be woken up on a system event, in that case waking the thread is managed by the scheduler of the OS
It's rather language specific.
Once you create a thread, it starts running.
A join operation is when your main process stops and waits for the thread to exit and capture a return code. It will block until your thread completes - that's rather the point, as it allows for a synchronization to occur - everything in your program is at a 'known state'.
Related is the detach operation, which is effectively saying 'I don't care any more'.

How to Wait and Terminate a TThread in Delphi (notifying the user when finished)

If an user provides information that is recorded in an excel file then I choose Excel COM to read the data.
However, as the user can repeat the process to N files and the process can take a while, I decided to move this routines to a separated thread.
Therefore, I need your advice to define how can I do this.
The worker thread cannot be destroyed until there is no more remaining files.
Inside the thread the data is loaded to a ClientDataSet and at the end is applied to database.
I need somehow notify the user when task is done, so he can decide if he will load another file and execute the thread again or finish the job.
How to properly destroy the thread and notify the user?
Should I create and destroy the thread to each file?
You can, but that is not a very efficient design. Put the files into a thread-safe queue, then start the thread if it is not already running, and then have the thread loop through the queue util it is empty. At that time, the thread can then be destroyed, or just put to sleep in case more files will be queued later on.
This design also allows you to process multiple files in parallel if you implement a thread pool. When you put a file into the queue, start a new thread if there is not already an idle thread waiting to be used. When a thread starts, pull the next available file from the queue. When that thread finishes, it can pull the next file from the queue, and if there is no file then go back into the pool for later reuse.
If so, How to properly destroy the thread and notify the user?
When you are ready to destroy a thread, call its Terminate() method (its Execute() needs to should check its Terminated property periodically and exit when set to true), then call its WaitFor() method (or equivalent, like MsgWaitForMultipleOjects(), which allows you to keep the message queue responsive while waiting for the thread to terminate), then free it from memory. The thread triggers its OnTerminate event after Execute() exits, however it is not safe to destroy the thread in the OnTerminate event handler. If you want to destroy the thread when the OnTerminate event is triggered (especially if you are not expecting the thread to terminate, such as if it threw an uncaught exception), you can post yourself an asynchronous notification, such as with PostMessage(), PostThreadMessage(), TThread.Queue(), etc, and then destroy the thread when that notification is processed at a later time.
How to set a thread to notify the user when the work is finished? By assigning the event OnTerminate?
Yes. Unless the thread is going to process multiple files before terminating, in which case the thread could manually send a notification in between each file.
It's better to create the thread to each file or create 1 thread and somehow control it's execution to every time for different files?
Creating and destroying a thread is not trivial for the OS, in terms of resources and processing, so you should re-use threads as much as possible. Make them sleep when they have nothing to do, unless they are going to be sleeping for a long time in which case you should destroy them to release their resources.

How do you detect that a TEvent has been set?

The Delphi XE2 documentation says this about TEvent:
Sometimes, you need to wait for a thread to finish some operation rather than waiting for a particular thread to complete execution. To do this, use an event object. Event objects (System.SyncObjs.TEvent) should be created with global scope so that they can act like signals that are visible to all threads.
When a thread completes an operation that other threads depend on, it calls TEvent.SetEvent. SetEvent turns on the signal, so any other thread that checks will know that the operation has completed. To turn off the signal, use the ResetEvent method.
For example, consider a situation where you must wait for several threads to complete their execution rather than a single thread. Because you don't know which thread will finish last, you can't simply use the WaitFor method of one of the threads. Instead, you can have each thread increment a counter when it is finished, and have the last thread signal that they are all done by setting an event.
The Delphi documentation does not, however, explain how another thread can detect that TEvent.Set event was called. Could you please explain how to check to see if TEvent.Set was called?
If you want to test if an event is signaled or not, call the WaitFor method and pass a timeout value of 0. If the event is set, it will return wrSignaled. If not, it will time out immediately and return wrTimeout.
Having said that, the normal usage of an event is not to check whether it's signaled in this manner, but to synchronize by blocking the current thread until the event is signaled. You do this by passing a nonzero value to the timeout parameter, either the constant INFINITE if you're certain that it will finish and you want to wait until it does, or a smaller value if you don't want to block for an indefinite amount of time.

Does TTimer.OnTimer causes a worker thread to synchronize with a main thread?

I have to work with legacy code. This code has a TTimer created in a main thread.
In OnTimer event the timer is checking periodically a state of some data in the worker thread.
pseudocode:
procedure MainForm.OnTimer(Sender: TObject);
begin
if WorkerThread.Data.State = full then
begin
WorkerThread.Free; //This freezes GUI.
end else
//Do something else.
end;
The problem is that I want to do some background operation when the WorkerThread is terminating. To avoid synchronization I've overriden DoTerminate method. However in this particular case, this is not helping and my GUI becomes frozen until the DoTerminate finishes.
Can I somehow avoid the freeze?
Thanks.
There's not enough code here to say anything with any certainty. However, calling Free on a thread results in a call to Terminate followed by a WaitFor. It's quite plausible that the wait is not returning which would be consistent with the frozen UI.
This is truly backwards. In any decent threading scheme, your thread will be notifying your gui-thread about a condition like .Data.State = full. You gui-thread or main-thread will then take appropriate action. One thing i am certain about is that WorkerThread.Free must be wrong. Trying to free a thread that's apparently blocked for whatever reason, is guaranteed to fail. Thread.Terminate will also fail if the thread is blocked, so no help there either.
Having a Timer monitor the status of a thread is never right. I never use the words always and never, but... I'll repeat: Having a Timer monitor the status of a thread is never right. Never ever. Don't even think about it.
turin

Mechanics of Condition.Signal()

If I had threads as below
void thread(){
while() {
lock.acquire();
if(condition not true)
{
Cond.wait()
}
// blah blah
Cond.Signal();
lock.release();
}
}
Well I guess my main question is that whether the signalling thread continues running for a while after cond.signal() or immediately gives up the CPU?. I would like it in some cases not to release the lock before the woken up thread finishes execution and in some other cases it may be beneficial to release the lock immediately after signalling, without waiting for the other woken thread to finish.
I understand that if there are any threads waiting on the condition then they get woken up on Cond.signal(). But what do you mean by woekn up - put on the ready queue or does the scheduler make sure that it runs immediately?.
and what about the signalling thread.. does it go to sleep on the same condtion upon signalling? .. so then some other thread has to wake it up to make it release the lock?.
This is in large part dependent on your environment (OS, library, language...) and how the synchronisation primitives are implemented. Since you haven't specified any I'll just give a general answer.
When putting a thread to sleep, most environment will choose to remove it from the scheduler's ready queue and the thread will give up its remaining CPU time. When woken up, the thread is simply placed back into the ready queue and will resume execution the next time the scheduler selects it from the queue.
It's also possible that the thread will do some active waiting (spinning) instead of being removed from the scheduler's ready queue. In this case, the thread will resume execution right away. Note that since a thread can still be run out of CPU of time while spinning, it might have to wait to be rescheduled before waking up. This is a useful strategy if your critical sections are very small and you don't want to pay for the scheduling overheads.
A hybrid approach would be to do a small amount of active waiting before removing the thread from the scheduler's ready queue.
As for the signaling thread, unless specified explicitly by your environment (I can't of any reasons but you never know), I wouldn't expect a call to signal() to block in a way that you have to wake it up. Signal() might have to synchronize itself with other threads calling signal() but those are implementation details and you shouldn't have to do anything about it.

Resources