|
Roger Stoltz wrote: The same call would be made if the user brings up Task Manager and kills the program/process.
hmm.. Noted.
Press: 1500 to 2,200 messages in just 6 days? How's that possible sir?
Dr.Brad :Well,I just replied to everything Graus did and then argued with Negus for a bit.
|
|
|
|
|
Calling TerminateThread for this function is a sin in Win32 (with barely any exceptions). See here[^] and here[^] here for details. Quote from MSDN:
TerminateThread is a dangerous function that should only be used in the most extreme cases. You should call TerminateThread only if you know exactly what the target thread is doing, and you control all of the code that the target thread could possibly be running at the time of the termination. For example, TerminateThread can result in the following problems:
- If the target thread owns a critical section, the critical section will not be released.
- If the target thread is allocating memory from the heap, the heap lock will not be released.
- If the target thread is executing certain kernel32 calls when it is terminated, the kernel32 state for the thread's process could be inconsistent.
- If the target thread is manipulating the global state of a shared DLL, the state of the DLL could be destroyed, affecting other users of the DLL.
This is one of the most frequent and serious mistakes Win32 programmers make. It creates a class of bug that's very hard to track down and is non-determinisitc.
Steve
|
|
|
|
|
if you want to accomplish what OP ask you have to use TerminateThread , I know well that this is the last resource for a programmer, but, again, if you don't have any other solution, you have to use it (This is the reason MS made it). Personally I hate to use it as I hate to use the task manager to kill a process. But, again, it is a matter of last resource.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
But if the code you're terminating is allocating memory on the heap (and probably most non-trivial threads do this), you just introduced the possibility of a deadlock.
Calling TerminateThread on an thread doing unknown things leaves the process in an undefined state. The only thing you can do is to move out the library call into a separate process and kill the process when aborting. All global resources will be freed by the OS, and all process resources don't have to be freed because the process is dead. The only safe way to kill unknown code is to kill its process.
|
|
|
|
|
Indeed your alternative is valid (and nice), even if (at least IMHO) the TerminateThread MSDN documentation is less severe (than you) about using it.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
CPallini wrote: even if (at least IMHO) the TerminateThread MSDN documentation is less severe (than you) about using it.
Actually I think MSDN underplays the issue; calling TerminateThread is an extremely serious issue.
Steve
|
|
|
|
|
Stephen Hewitt wrote: Actually I think MSDN underplays the issue;
A don't know if they do that above stated.
Stephen Hewitt wrote: calling TerminateThread is an extremely serious issue.
Oh yes, but it's context-dependent and, at least it's no more serious that ternminating abrptly a thread.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
It's not an option; in the same way chopping off your head is not a cure for a brain tumor.
Steve
|
|
|
|
|
A bit crude. That said, I don't agree with you.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
Then consider this:
==================
// Console.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <process.h>
using namespace std;
unsigned __stdcall ThreadFn(void *)
{
for (;;)
{
// Comment these two lines out and the program will not deadlock. With them it will!
int *pInt = new int;
delete pInt;
}
return 0;
}
int main(int arvc, char* argv[])
{
for (;;)
{
unsigned unused;
unsigned long res = _beginthreadex(
NULL, // void *security
0, // unsigned stack_size
&ThreadFn, // unsigned ( __stdcall *start_address )( void * )
NULL, // void *arglist
0, // unsigned initflag
&unused // unsigned *thrdaddr
);
if (res==0)
{
cerr << "Failed to create thread!" << endl;
return 1;
}
for (int i=1; i<=1000; ++i)
{
int *pInt = new int;
delete pInt;
cout << i << " ";
}
HANDLE hThread = reinterpret_cast<HANDLE>(res);
// Comment this line out and the program will not deadlock. With it it will!
TerminateThread(hThread, 0);
CloseHandle(hThread); // We don't need the HANDLE anymore so close it.
}
return 0;
}
Steve
|
|
|
|
|
Of course I will try it. But, anyway, IMHO, extreme samples cannot prevent us to apply (risky!?) paths in ordinary life.
(Remembering, again, that I consider TerminateThread the last option).
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
Allocating memory is hardly an exterme example. Anyway, if this doesn't convince you I don't know what will.
Steve
|
|
|
|
|
Stephen Hewitt wrote: Anyway, if this doesn't convince you I don't know what will.
But you don't have to.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
No, I don't have to. Still, these forums are to share knowledge so I make an effort to be helpful if I can. This entails both telling people what and what not to do.
Steve
|
|
|
|
|
Stephen Hewitt wrote: No, I don't have to. Still, these forums are to share knowledge so I make an effort to be helpful if I can
Very good.
Stephen Hewitt wrote: This entails both telling people what and what not to do.
Not so good, I prefer the following:
This entails telling people about your opinion on both what and what not to do.
Cheers
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
CPallini wrote: Not so good, I prefer the following:
This entails telling people about your opinion on both what and what not to do.
Whose opinion would I tell other than my own?
Anyway, have you tried the program I posted yet? I am curious to see if that changes you mind.
Steve
|
|
|
|
|
Stephen Hewitt wrote: Whose opinion would I tell other than my own?
As stated, it appeared a bit axiomatic.
Stephen Hewitt wrote: Anyway, have you tried the program I posted yet? I am curious to see if that changes you mind.
Not I don't, but of course I will. And you will know about.
I wondering if OP expected such a long debate.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
CPallini wrote: I wondering if OP expected such a long debate.
He'll live
Steve
|
|
|
|
|
I just tried (as promised) your sample code. Indeed it's impressive: it hangs after few (overall) iterations. Observations:
(1) Yes, it is extreme: the two threads are doing heap memory allocation/deallocation concurrently (and nothing else).
(2) The code proposed in OP already hangs (that was the problem to solve).
Bottom line: I still think that you can use TerminateThread as last resource, provided the main thread waits for secondary thread expiration without doing anything else (oh yes it can sleep for a while!)
Cheers
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
CPallini wrote: (1) Yes, it is extreme: the two threads are doing heap memory allocation/deallocation concurrently (and nothing else).
No, it isn't extreme. Allocating memory is something almost every thread will do. If the thread is terminated while it holds the heap lock all memory allocation will fail in the whole process. All I've done is stripped down the code to a bare minimum. In a more realistic situation it's worse: the terminate will work sometimes then, for no apparent reason, all memory allocation will mysteriously fail and result in a deadlock. Try tracking something like that down: the point at which the deadlock occurs is far removed from the source (in fact in a different and long dead thread). Memory allocation isn’t the only example of this kind of thing: any function that uses critical sections – such as many of the Win32 API calls – will exhibit the same problem.
In short: calling TerminateThread is reckless and dangerous and almost never safe. After calling TerminateThread the process is in an unknown and possibly invalid state. You can not make quality software like this.
Steve
|
|
|
|
|
Stephen Hewitt wrote: In short: calling TerminateThread is reckless and dangerous and almost never safe. After calling TerminateThread the process is in an unknown and possibly invalid state.
In short (IMHO): calling TerminateThread maybe the last option in situation like the ont the OP depicted (unless you can change the overall design the way you suggested).
Stephen Hewitt wrote: You can not make quality software like this.
I agree on the above.
Cheers.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
Don't use TerminateThread . See here[^] for why not.
Steve
|
|
|
|
|
Thanks steve, lots of points to be noted. Also nice that there's .net illustration too. Reading them. Thanks
Press: 1500 to 2,200 messages in just 6 days? How's that possible sir?
Dr.Brad :Well,I just replied to everything Graus did and then argued with Negus for a bit.
|
|
|
|
|
Dear All;
I am hosting a microsoft web browser control (assuming it has got a variable: m_webBrowser) on a dialog box.
I want to capture a screen shot of the content of the web browser (excluding the main window).
Does anyone know or have any idea how to save the content of web browser as an image?
I have tried this:
<br />
RECT rc;<br />
HWND hWnd = m_webBrowser.GetSafeHwnd();<br />
::GetWindowRect (hWnd,&rc); <br />
HDC hDC = ::GetDC(0);<br />
HDC memDC = ::CreateCompatibleDC ( hDC );<br />
HBITMAP memBM = ::CreateCompatibleBitmap ( hDC, rc.right-rc.left, rc.bottom-rc.top );<br />
::SelectObject ( memDC, memBM );<br />
::BitBlt( memDC, 0, 0, rc.right-rc.left, rc.bottom-rc.top , hDC, rc.left, rc.top , SRCCOPY );<br />
But it only saves the visible area of the web browser and not all the content !!!
I will be very gratefull if anyone can help with this problem as it is giving me a real headache .
llp00na
|
|
|
|
|