|
TerminateThread is a VERY agressive function and I would aviod using it AT ALL COSTS.
TerminateThread is used to cause a thread to exit. When this occurs, the target thread has no chance to execute any user-mode code and its initial stack is not deallocated. DLLs attached to the thread are not notified that the thread is terminating.
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.
A thread cannot protect itself against TerminateThread, other than by controlling access to its handles. The thread handle returned by the CreateThread and CreateProcess functions has THREAD_TERMINATE access, so any caller holding one of these handles can terminate your thread.
If the target thread is the last thread of a process when this function is called, the thread's process is also terminated.
The state of the thread object becomes signaled, releasing any other threads that had been waiting for the thread to terminate. The thread's termination status changes from STILL_ACTIVE to the value of the dwExitCode parameter.
Terminating a thread does not necessarily remove the thread object from the system. A thread object is deleted when the last thread handle is closed.
As you can see, using TerminateThread is just asking for problems.
Tim Smith
Descartes Systems Sciences, Inc.
|
|
|
|
|
Did you think about asynchronous I/O? It is intended to solve exactly such type of problems.
|
|
|
|
|
Asynchronous I/O is unfortunately not possible because all the communication protocol is packaged up into an ActiveX which cannot be changed.
And the reason for several worker threads is:
1.responsiveness of GUI to be preserved
2.queue requests for other data retrieval during the blocked period of time
The worker threads themselves are meant to play the role of asynchronous calls.
Thanks
Pepe
|
|
|
|
|
I dynamic created a CEdit window, and it doesn't handle all the short cut keys ..
so I decide to handle those ctrl+c, ctrl+v etc.
maybe there is an easier way, please tell me.
created it..
dwStyle = WS_CHILD|ES_AUTOHSCROLL;
Create(dwStyle, m_rc, m_pProp->GetCtrlParent(), GetCtrlID());
and want all keys ...
UINT CPropTreeItemEdit::OnGetDlgCode()
{
return CEdit::OnGetDlgCode()|DLGC_WANTALLKEYS;
}
override OnChar function...
void CPropTreeItemEdit::OnChar( UINT nChar, UINT nRepCnt, UINT nFlags )
BOOL bControl = GetKeyState(VK_CONTROL) & 0x8000;
if (bControl)
{
TRACE("%c",nChar);
switch (nChar)
{
case 'a':
{
SetSel(0,-1);
}
break;
case 'x':
Cut();
break;
case VK_INSERT:
case 'c':
Copy();
break;
case 'v':
Paste();
break;
}
}
but when i hit key control key, the character value is always 17 which is probably the control key value,
How can I get a 'a' or 'x'?
|
|
|
|
|
I think you've probably missed a flag or something for the keys to not just work, but in answer to the question, under each case statement, use
if (GetAsynchKeyState(VK_CONTROL))
to find out if the control key is also down. Do a GetAsynchKeyState(VK_CONTROL); before the switch to clear the buffer.
Christian
I have come to clean zee pooollll. - Michael Martin Dec 30, 2001
Picture the daffodil. And while you do that, I'll be over here going through your stuff.
|
|
|
|
|
Can anybody show me the way to create image file in memory with GDI+?
thanks
Mazy
Don't Marry a Person You Can Live With...
Marry Someone You Can Not Live Without
|
|
|
|
|
Have you considered reading the docs at the URL I gave you ?
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdicpp/gdip_cpp_classes_01b_0nw3.asp
Bitmap bitmap (1024, 768,PixelFormat24bppRGB );
Last time I looked only one of the pixel formats worked, it was either this one, or 32bppRGB, but accessing hte individual bits still returned BGR.
Christian
I have come to clean zee pooollll. - Michael Martin Dec 30, 2001
Picture the daffodil. And while you do that, I'll be over here going through your stuff.
|
|
|
|
|
This problem involves floating point variables. When ever I add or subtract to a floating point variable I get strange numbers. For example if I add 0.5f to 5.0f, I get 5.499999999999 instead of 5.5. Here is an example:
float fExample = 5.0f;
fExample = fExample + 0.5f;
// fExample is now 5.499999999 !!!!
Is there something I am doing wrong, or is there a way of doing this without getting those ridiculous values.
Thanks in advance,
James Bird
|
|
|
|
|
Floating point is not entirely accurate. Doubles are more accurate than floats.
Why do you need 5.5 instead of 5.499999 ?
Christian
I have come to clean zee pooollll. - Michael Martin Dec 30, 2001
Picture the daffodil. And while you do that, I'll be over here going through your stuff.
|
|
|
|
|
Christian Graus wrote:
Why do you need 5.5 instead of 5.499999 ?
Thats what i was thinking...are they calculating the trajectory of a missle or something...? Maybe you shouldn't say anything..;P
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
If its just the display output that is the problem, you might want to have a look at this thread: here
|
|
|
|
|
Floating point is stored in base 2 and thus can have trouble representing numbers that look perfectly normal to us. Also, addition is inherently poor in floating point while multiplication works much better. If you can avoid repeatedly adding small numbers to a large number and instead perform a single add, the quality of the floating point number is much better.
For example:
float a = 1000;
for (int i = 0; i < 10000; i++)
{
a += 0.5;
}
float a = 1000;
for (int i = 0; i < 10000; i++)
{
float b = a + (float) i * 0.5;
}
Tim Smith
Descartes Systems Sciences, Inc.
|
|
|
|
|
I know what a heap is, I know what a stack is but how do they relate to each other? I'm trying to reach a better understanding of memory management and not being able to put them in context is really throwing me.I know the question is a bit vague but so is my understanding at this point.
To overcome everything is to reach an invisible height where users cease to exist
|
|
|
|
|
Stack works on a push pop concept, heap is random.
stack is used for temporary static variables, heap is used to create dynamic variables.
Thats why you get mem leaks with:
Blah* blah = new Blah;
if no delete follows
but never with
Blah blah;
whatever is pushed onto the stack at startup is removed automatically at the end of the current scope, block, function thingy.
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
HockeyDude wrote:
stack is used for temporary static variables, heap is used to create dynamic variables.
Thank you that clarifies everything!
To overcome everything is to reach an invisible height where users cease to exist
|
|
|
|
|
No worries be happy!
*dances like Harry Bellafonte*
Daaaaaaaaao
DaaaaaaaaaOh..
DB developer and me want to go home.
Left key, right key, left key type!!!
It's almost daylight here, so i'm gonna quit singing...
Nite'
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
HockeyDude wrote:
current scope, block, function thingy
Nish
Nish was here, now Nish has gone;
He left his soul, to turn you on;
Those who knew Nish, knew him well;
Those who didn't, can go to hell.
I like to on the Code Project
Sonork ID 100.9786 voidmain
www.busterboy.org
|
|
|
|
|
it 5:00 in the morning here Nish I'm at a loss for words.
Later brutha!
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
HockeyDude wrote:
it 5:00 in the morning here Nish I'm at a loss for words
Aaaah
A fellow nocturnal creature.
HockeyDude wrote:
Later brutha!
Yup. later!
Nish
Nish was here, now Nish has gone;
He left his soul, to turn you on;
Those who knew Nish, knew him well;
Those who didn't, can go to hell.
I like to on the Code Project
Sonork ID 100.9786 voidmain
www.busterboy.org
|
|
|
|
|
Nish [BusterBoy] wrote:
A fellow nocturnal creature.
Yup like a racoon.
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
Let's see if I can shed some more light on the subject.
There are basically two locations where memory can be allocated in C++: on the stack or on the heap.
The stack is used by the compiler mostly to allocate local variables whose size is well known at compile time. Every time you define a local variable (inside a function block), the compiler reserves a block of bytes for the size taken up by the variable. This is a very quick operation because all the compiler does is assign the address to the variable and move its "stack pointer" down by the size of the variable. This is called pushing the stack. When the variable goes out of scope the compiler does the opposite -- it pops the stack -- and the memory is reclaimed. Thus, memory allocated on the stack is automatically reclaimed by the compiler, and it's all very quick because it's all done in one location -- the end of the stack, if you will. The stack is also used whenever a function is called to hold its return address and its parameters (if any).
The heap is quite different. It's typically used to allocate variables that you plan to keep longer than duration of a function block, or variables whose size is not known until run-time (such as dynamic arrays). In C++, memory is taken from the heap via the new operator (or via the global C function "malloc"). When this happens, the heap manager looks for a block of memory large enough to hold the contents of your variable and returns the beginning address of that block. This block of memory stays allocated until your program calls the delete operator on that memory (or "free" if malloc was used) or until the program ends. By the way, allocating memory on the heap is much slower than allocating from the stack, so the stack should be used if the variable will not be needed outside the block where it was allocated and its size is known at compile-time. In addition, since the stack's memory is automatically reclaimed, it requires less housekeeping on the part of the programmer (to prevent memory leaks). However, the stack should ONLY be used when the variable will not be referenced outside the block where it was allocated, otherwise you'll be left with an invalid memory address which when used will cause the program to crash.
I hope to have cleared things up.
Regards,
Alvaro
Behind a beautiful woman there's usually a guy who just couldn't wait to get rid of her.
|
|
|
|
|
How can I do the following, but correctly?
LPSTR fileName = "data.dat";
class MyClass{
MyClass(){ CFile myFile(fileName, BLAH); }
~MyClass(){}
};
#define AfxSetFileName(file) (fileName = file)
I don't think I'm missing anything. Anyways i'm getting a linker error fileName already defined. Somebody wanna enlighten me and explain why...?
It's all in the one header file, if this makes a difference.
Also how do I prevent name collisions with third party libs using namespace on the global variable...?
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
You should declare your global variables in a .cpp file, and redeclare that variable in the header file with 'extern'. Because when you include the header into a second file, the variable gets redeclared and then you get a linker error, duplicate definition.
example:
.cpp file -
int g_Index = 0;
.h file -
extern int g_Index;
|
|
|
|
|
I can't put it in the cpp. There is none. It would defeat the purpose of my needs.
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
HockeyDude wrote:
Also how do I prevent name collisions with third party libs using namespace on the global variable...?
The other half has been answered. To do it in a namespace, just decalre one
namespace MyNamespace
{
extern int g_int;
}
and in the .cpp declare it
int MyNamespace::g_int;
Christian
I have come to clean zee pooollll. - Michael Martin Dec 30, 2001
Picture the daffodil. And while you do that, I'll be over here going through your stuff.
|
|
|
|