In delphi, a method in TThread is terminate. It seems a subthread can not kill another thread by calling terminate or free.
For example
A(main form), B (a thread unit), C (another form).
B is sending data to main form and C (by calling syncronize), we tried to terminate B within C while B is executing by calling B.terminate. But this method does not work and B is still working until it ends in execute method.
Please help. Thank you in advance.
You have to check for Terminate in the thread for this to work. For instance:
procedure TMyThread.Execute;
begin
while not Terminated do begin
//Here you do a chunk of your work.
//It's important to have chunks small enough so that "while not Terminated"
//gets checked often enough.
end;
//Here you finalize everything before thread terminates
end;
With this, you can call
MyThread.Terminate;
And it'll terminate as soon as it finishes processing another chunk of work. This is called "graceful thread termination" because the thread itself is given a chance to finish any work and prepare for termination.
There is another method, called 'forced termination'. You can call:
TerminateThread(MyThread.Handle);
When you do this, Windows forcefully stops any activity in the thread. This does not require checking for "Terminated" in the thread, but potentially can be extremely dangerous, because you're killing thread in the middle of operation. Your application might crash after that.
That's why you never use TerminateThread until you're absolutely sure you have all the possible consequences figured out. Currently you don't, so use the first method.
Actually,
currently most voted answer to this question is incorrect (so as 34 upvoters...) in regard how to forcefully kill a thread.
You do not use ThreadId as a parameter to TerminateThread procedure. Using ThreadId will cause most likely an "Invalid handle" error or in worse case scenerio - will kill a different thread.
You should pass a thread handle as a parameter:
TerminateThread(MyThread.Handle);
More about differences between thread's handle and id can be found here.
Edit
Seems #himself corrected his mistake after seeing my answer, so this is no longer relevant.
Terminate does not kill a thread; it sets the Terminated property to inform the thread that it needs to terminate. It's the thread's responsibility to watch for Terminated and shut itself down gracefully.
All the Terminate method does is it sets the Terminated property to true. So you have to manually keep checking that property and then exit the thread method when it is set to true.
If you might want to terminate a thread then you could be better off spawning another app and killing that if you think its failed - windows will then tidy up after you.
Related
I don't want to execute the current instructions in the current processmessage loop, but instead execute it in the next processmessage loop. Is their a good way to do it ? TThread.queue seam to be what i m looking for except that TThread.queue can not be executed from the main Thread :( I m under firemonkey also if it's matter
TThread.Queue() is asynchronous only if it is called in a worker thread. When TThread.Queue() is called in the main thread, it is synchronous instead 1.
To do what you are asking for, you can use TThread.CreateAnonymousThread() or TTask.Run() to create a worker thread that then calls TThread.Queue().
1: please vote on RSP-15427 Add an option to let TThread.Queue() run asynchronously when called by the main UI thread.
The following error is occuring when passing values from a model to a parameter inside an If Statement.
This is the code the issue is occurring, I'm pretty sure its not the ValidateUserPassword method.
if (PSFNetSystem.ValidateUserPassword(model.Server, model.Username, model.Password) < 0)
{
ModelState.AddModelError("Password", "Failed to login");
return View(model);
}
Any help is appreciated, thanks.
Short answer: You can click on the "thread" icon to the right to force the evaluation.
Long answer:
When you evaluate a method in the debugger, the debugger/CLR sets the context of the current thread to the method being evaluated, sets a guard breakpoint, freezes all threads except the current thread, then continues the process. When the breakpoint is hit, the debugger restores the thread to its previous state and uses the return value to populate the window.
Because only one thread is running, it's possible to create deadlock situations if the evaluation thread takes a lock that's already held by another thread. If the CLR detects a possible deadlock it aborts the evaluation and the debugger ultimately shows that message.
Clicking the button to allow all threads to run means that we don't freeze the other threads when retrying the evaluation. This will allow the evaluation to proceed, but has the disadvantage of breakpoints on other threads being ignored.
BTW, If you are writing code that you know will likely deadlock if it's evaluated, you can call Debugger.NotifyOfCrossThreadDependeny. This will cause the behavior you are seeing.
It is because it needs to run the code to show you the result in the debugger. You can press the icon at the right to evaulate it, or you can go to Options -> Debugging and turn off "Enable property evaluation or other implicit function calls".
I call dispatch_async(dispatch_get_main_queue()from several background threads. However, it appears that occasionally the code in the dispatch block is not executed. Could this be because i dispatch asynchronously and the thread exits before the main queue can execute the code?
Have you tried putting an NSLog in the beginning of your code snippet to be absolutely sure that it's not executing? Sometimes an if statement with faulty logic will pre-terminate your code. (From my past experience ;])
The moment the dispatch_async() call returns, it's not important whether or not the thread that invoked it subsequently exits or not - the "request is in the system" so to speak! Something else is happening in those "occasional" cases. Does your program have a run loop or call dispatch_main() at the end of its main function? Not clear whether this is a Cocoa/iOS/POSIX application you're describing.
Let me show you the function first:
for (i=0; i<3;i=i+2){
pthread_create(&thread1, NULL, &randtrack, (void *)&rnum_array[i]);
pthread_create(&thread2, NULL, &randtrack, (void *)&rnum_array[i+1]);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
}
print final result here;
My understanding is after two threads are created, the parent thread will blocked at join(thread1), what is the thread 2 actually come back earlier than thread1? How can make longer thread always stay behind?
Thanks
If thread2 finishes and thread1 hasn't, you'll continue waiting until thread1 finishes. Then you'll wait until thread2 finishes, which will complete more or less instantaneously. The order in which you wait for the threads won't matter (unless the threads try to interact with each other directly, such as by calling pthread_kill or pthread_join on each other).
Update: Your design is completely wrong for what you're actually trying to do. You want to do this:
Create a structure to track the work that needs to be done. It should be protected by a mutex, track how many threads are currently working, and what the next work unit that needs to be assigned is.
When you create the threads, have them rung a function that acquires the mutex, grabes the next unit of work, increments the number of threads running, and then does the work.
When a thread completes a work unit, it should acquire the mutex, decrement the number of threads running, and see if there's more work to do. When there's no work to do, the thread should terminate.
You can now wait for all threads to terminate, which will only happen when all the work is done. This eliminates the loop over the work units.
And please learn a very important general rule -- threads are just the things that get work done. What you want your code to focus on is doing the work, not how it will be done. Try to wait for work to be done, not for threads to be done.
As far as I understand, pthread_exit() exactly equals to return when you need terminate a thread with a return value. When people can use the consistent way, i.e. return, to do the job why Pthread define such a duplicated interface?
Two reasons that come to my mind: pthread_exit
Allows you to exit a thread from any depth in the call stack.
Must be called on the main thread if the TLS keys for the main thread are to have their free functions called. And here as well: "Any cancellation cleanup handlers that have been pushed and not yet popped are popped in the reverse order that they were pushed and then executed. After all cancellation cleanup handlers have been executed, if the thread has any thread-specific data, appropriate destructor functions will be called in an unspecified order... An implicit call to pthread_exit() is made when a thread other than the thread in which main() was first invoked returns from the start routine that was used to create it. The function's return value serves as the thread's exit status."
If you're going to call pthread_exit a duplicated interface, then you should also call exit() a duplicated interface, since you could exit the program at an arbitrary point. You probably want to call pthread_exit() when you have some sort of error condition where you simply cannot continue. Or, alternatively, you've found whatever value you're looking for inside of the thread.
As for it's real existence, according to the documentation:
An implicit call to pthread_exit() is made when a thread other than the thread in which main() was first invoked returns from the start routine that was used to create it. The function's return value serves as the thread's exit status.
So if you did a return <some pointer> from the thread, or simply reached the end, pthread_exit() would be called anyway. It's the same with exiting from main(), if you return 0 you're actually calling exit(0). The function has to exist, otherwise the kernel would not have a way of determining if the thread exited.