I have a QThread that fetches data from the web. Sometimes the user asks for something else, and the data needs to be fetched changes as well.
In my current configuration, I call terminate() upon the thread, change the input data, and call start() on the thread again. Now, that works fine, but sometimes I get the main eventloop stuck when calling isRunning() or isFinished() upon a terminated thread. It gets stuck forever, and does not recover until I kill the process.
Why would isRunning() or isFinished() hung in the first place? They don't suppose to block.
Is this workflow acceptable? If not, how can I stop a thread's process when I don't need it no more (or how can I abandon it)?
Don't use terminate(), read the warning in the documentation.
Whil it is possible to restart a QThread, restarting threads usually is not a good idea, there should be a better solution to do what you're trying to do.
It seems that in some cases, the thread becomes unusable after termination, and isRunning() and isFinished() may hang the calling thread, even if called only after the TERMINATED signal.
My workaround was to terminate a thread, forget about it and start a new one.
Related
I have read that SendMessage() should not be used to access UI controls from other threads, but I'm not sure I know why, the only reason that I can think of is since SendMessage() is a blocking call, then it could cause a deadlock in certain situations.
But is this the only reason not to use it?
Edit: This article talks about the reasons not to use SendMessage() but I don't find it to be very clear (it is intended for .NET).
It is best to keep in mind that the odds that you will write correct code are not very good. And the generic advice is don't do it! It is never necessary, the UI thread of a GUI program in Windows was entirely structured to make it simple to allow code that runs on another thread or inside a process affect the UI of the program. The point of the message loop, the universal solution to the producer-consumer problem. PostMessage() is your weapon to take advantage of it.
Before you forge ahead anyway, start by thinking about a simple problem that's very hard to solve when you use SendMessage. How do you close a window safely and correctly?
Given is that the exact moment in time that you need to close the window is entirely unpredictable and completely out of sync with the execution of your worker thread. It is the user that closes it, or asks the UI thread to terminate, you need to make sure that the thread has exited and stops calling SendMessage before you can actually close the window.
The intuitive way to do this is to signal an event in your WM_CLOSE message handler, asking the thread to stop. And wait for it to complete, then the window can close. Intuitive, but it does not work, it will deadlock your program. Sometimes, not always, very hard to debug. Goes wrong when the thread cannot check the event because it is stuck in the SendMessage call. Which cannot complete since the UI thread is waiting for the thread to exit. The worker thread cannot continue and the UI thread cannot continue. A "deadly embrace", your program will hang and needs to be killed forcibly. Deadlock is a standard threading bug.
You'll shout, "I'll use SendMessageTimeout!" But what do you pass for the uTimeout argument and how do you interpret an ERROR_TIMEOUT error? It is pretty common for a UI thread to go catatonic for a while, surely you've seen the "ghost window" before, the one that shows 'Not Responding` in the title bar. So an ERROR_TIMEOUT does not reliably indicate that the UI thread is trying to shut down unless you make uTimeout very large. At least 10 seconds. That kinda works, getting the occasional 10 second hang at exit is however not very pretty.
Solve this kind of problem for all the messages, not just WM_CLOSE. WM_PAINT ought to be next, another one that's very, very hard to solve cleanly. Your worker thread asks to update the display a millisecond before the UI thread calls EndPaint(). And thus never displays the update, it simply gets lost. A threading race, another standard threading bug.
The third classic threading bug is a fire-hose problem. Happens when your worker thread produces results faster than the UI thread can handle them. Very common, UI updates are pretty expensive. Easy to detect, very hard to solve and unpredictable when it occurs. Easy to detect because your UI will freeze, the UI thread burns 100% core trying to keep up with the message rate. It doesn't get around to its low-priority tasks anymore. Like painting. Goes wrong both when you use SendMessage or PostMessage. In the latter case you'll fill the message queue up to capacity. It starts failing after it contains 10000 unprocessed messages.
Long story short, yes, SendMessage() is thread-safe. But thread-safety is not a transitive property, it doesn't automatically make your own code thread-safe. You still suffer from all the things that can go wrong when you use threads. Deadlocks, races, fire-hosing. Fear the threading beast.
I've been searching and reading about killing threads (C posix threads), and everybody says that is not a good idea because a thread should make its work and then return... but my problem is the next:
I'm reciving messages in my local network (using the recvfrom function), but this function "blocks" my program, I mean, if I don't revice any messege the function keeps locked (forever) until it recives something.
To avoid this, I thought to use threads, so, while my main thread is "counting", my second thread is try to recive messages. If in a determinated time (i.e. 1 second), my second thread is still waiting for a message (is locked in the recvfrom function) I need to "kill it" and then create another thread to start again (and try to recive messages from another IP). This means that not always my thread going to finish its work and I can't wait forever...
So far I can do that (create a lot of threads and recive the messages from the IP I'm interested in), but I don't know how to kill the threads that never recived anything...
Someone knows how to kill the threads? Or they are killed automatically when my main program returns?
Thank you and really sorry for my poor english...
Looks like its related to one of my questions How to avoid thread waiting in the following or similar scenarios (want to make a thread wait iff its really really necessary)?
But its .net, though (code sample is in C#)
Essentially i spawned new thread and performing some i/o oeprations and its a blocking call.
And for some reason it just waits foreve, i do have timeout so that i can abort the thread 'abort' method.
Rearchitect so the thread can receive messages from any IP. That way, you can try to receive messages from another IP without having to disturb the 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
I've got a service that I need to shut down and update. I'm having difficulties with this in two different cases:
I have some threads that sleep for large amounts of time. Obviously I can't wait for them to wake up to finish shutting down the service. I had a thought to use an AutoResetEvent that gets set by some controller thread when the sleep interval is up (by just checking every two seconds or something), and triggering it immediately at OnClose time. Is there a better way to facilitate that?
I have one thread that makes a call to a blocking method call (one which I cannot modify). How do you signal such a thread to stop?
I'm not sure if I understood your first question correctly, but have you looked at using WaitForSingleObject as an alternative to Sleep? You can specify a timeout as well as an object to wait on, so if you want it to wake up earlier, just signal the object.
What exactly do you mean by "call to a blocking thread"? Or did you just mean a blocking call? In general, there isn't a way to interrupt a thread without forcefully terminating it. However, if the call is a system call, there might be ways to return control by making the call fail, eg. cancelling I/O or closing an associated handle.
For 1. you can get your threads into an interruptable Sleep by using SleepEx rather than Sleep. Once they get this shutdown kick (initiated from your termination logic using QueueUserApc), you can detect it happened using the return code from SleepEx and terminate those threads accordingly. This is similar to the suggestion to use WaitForSingleObject, but you don't need another per-thread handle that's just used to terminate the associated thread.
The return value is zero if the
specified time interval expired.
The return value is WAIT_IO_COMPLETION
if the function returned due to one or
more I/O completion callback
functions. This can happen only if
bAlertable is TRUE, and if the thread
that called the SleepEx function is
the same thread that called the
extended I/O function.
For 2., that's a tough one unless you have access to some resource used in that thread that can cause the blocking call to abort in such a way that the calling thread can handle it cleanly. You may just have to implement code to kill that thread with extreme prejudice using TerminateThread (probably this should be the last thing you do before exiting the process) and see what happens under test.
An easy and reliable solution is to kill the service process. A process is the memory-safe abstraction of the OS, after all, so you can safely terminate one without regard for process-internal state - of course, if your process is communicating or fiddling with external state, all bets are off...
Additionally, you could implement the solution which OS's themselves commonly do: one warning signal asking the process to clean up as best possible (which sets a flag and gracefully exits what can be gracefully stopped), and then forceful termination if the process doesn't exit by itself (which ends pesky things like blocking I/O).
All services should be built such that forceful termination isn't harmful, since these processes are system managed and may be terminated by things such as a reboot - i.e., your service ideally should permit this without corrupting storage anyhow.
Oh, and one final warning; windows services may share a process (I presume for efficiency, though it strikes me as an avoidable optimization), so if you go this route, you want to make sure your service is not sharing a process with other services. You can ensure this by passing the option SERVICE_WIN32_OWN_PROCESS to ChangeServiceConfig.
I have a threading problem with Delphi. I guess this is common in other languages too. I have a long process which I do in a thread, that fills a list in main window. But if some parameters change in the mean time, then I should stop current executing thread and start from the beginning. Delphi suggests terminating a thread by setting Terminated:=true and checking for this variable's value in the thread. However my problem is this, the long executing part is buried in a library call and in this call I cannot check for the Terminated variable. Therefore I had to wait for this library call to finish, which affects the whole program.
What is the preferred way to do in this case? Can I kill the thread immediately?
The preferred way is to modify the code so that it doesn't block without checking for cancellation.
Since you can't modify the code, you can't do that; you either have to live with the background operation (but you can disassociate it from any UI, so that its completion will be ignored); or alternatively, you can try terminating it (TerminateThread API will rudely terminate any thread given its handle). Termination isn't clean, though, like Rob says, any locks held by the thread will be abandoned, and any cross-thread state protected by such locks may be in a corrupted state.
Can you consider calling the function in a separate executable? Perhaps using RPC (pipes, TCP, rather than shared memory owing to same lock problem), so that you can terminate a process rather than terminating a thread? Process isolation will give you a good deal more protection. So long as you aren't relying on cross-process named things like mutexes, it should be far safer than killing a thread.
The threads need to co-operate to achieve a graceful shutdown. I am not sure if Delphi offers a mechanism to abort another thread, but such mechanisms are available in .NET and Java, but should be considered an option of last resort, and the state of the application is indeterminate after they have been used.
If you can kill a thread at an arbitrary point, then you may kill it while it is holding a lock in the memory allocator (for example). This will leave your program open to hanging when your main thread next needs to access that lock.
If you can't modify the code to check for termination, then just set its priority really low, and ignore it when it returns.
I wrote this in reply to a similar question:
I use an exception-based technique
that's worked pretty well for me in a
number of Win32 applications.
To terminate a thread, I use
QueueUserAPC to queue a call to a
function which throws an exception.
However, the exception that's thrown
isn't derived from the type
"Exception", so will only be caught by
my thread's wrapper procedure.
I've used this with C++Builder apps very successfully. I'm not aware of all the subtleties of Delphi vs C++ exception handling, but I'd expect it could easily be modified to work.