|
John M. Drescher wrote:
The Sleep() function is not from the Windows API, is it?
It is part of the platform SDK.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
I know. My point is if he/she is using that one a 3ms delay is impossble.
John
|
|
|
|
|
The Sleep() function is from the Windows API and tends to be highly accurate particularly when runs from a thread operating at a Real-time priority level.
I have read the article you refer to and was also under that impression, but when I actually tested the system using this method with the HighPerformance counter function I found that the Sleep() function operated reliably down to 1ms and returned virtually immediately.
When I loaded the system down by performing a lot of highly computational programs, the accuracy deminished to 1.1ms - 0.1ms of delay was added due to system overhead.
(I am however running on a 2GHz Celeron system under XP Pro, maybe that's make a significant difference)
|
|
|
|
|
Thanks for the info. I have not tested this recently but with previous operating systems this information was correct. MS must have changed the implementation in XP.
John
|
|
|
|
|
PostMessage should not give you an access violation, no matter what parameters you pass so the problem must be with obj.
John
|
|
|
|
|
Hi Everyone,
I implemente a thread in a MFC application that can be started and stopped through 2 buttons. My problem: After i click the Stop button, the while-loop doesn't break, meaning that WaitForSingleObject does never return WAIT_OBJECT_0. How can i terminate a thread like this using wait for single object?
I noticed that some calls to PeekMessage inside the while loop make WaitForSingleObject return WAIT_OBJECT_0.
I really don't understand why this isn't working! Please can anybody help??
Jason
//-------------------------------------------------------------------------
void CAnyDlg::OnStart()
{
// declarations
DWORD dwId;
// start the thread
m_bThread=true;
if(m_hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)StartThread,(LPVOID)this,0,&dwId))
}
//-------------------------------------------------------------------------
void CAnyDlg::OnStop()
{
MSG msg;
while(::WaitForSingleObject(m_hThread,100)!=WAIT_OBJECT_0))
{
m_bThread=false;
}
}
//-------------------------------------------------------------------------
DWORD CAnyDlg::StartThread(LPVOID lpParam)
{
((CAnyDlg*)lpParam)->Thread();
return 0;
}
//-------------------------------------------------------------------------
void CAnyDlg::Thread()
{
while(m_bThread)
{
m_cstaAnyStatic.SetWindowText("Test");
}
}
//-------------------------------------------------------------------------
|
|
|
|
|
jason99 wrote:
...the while-loop doesn't break, meaning that WaitForSingleObject does never return WAIT_OBJECT_0.
Nor should it. When the Stop button is clicked, you are waiting 1/10 of a second for the secondary thread object to become signaled. Since there is no code in place to signal it, WAIT_TIMEOUT is returned. Once that happens, m_bThread is set to false , which should cause the loop in CAnyDlg::Thread() to stop, but does nothing for the loop in CAnyDlg::OnStop() , which only stops once WAIT_OBJECT_0 is returned.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
OK, that is right. The first call to WaitForSingle object will surely return WAIT_TIMEOUT. But when the bool is switched, the loop in CAnyDlg::Thread() stops. This means that the created thread will terminate sometime later. From this point on, a continous call to WaitForSingleObject should return WAIT_OBJECT_0 after some time. But that doesn't happen.
Tha fact that concerns me is that the code works if i take away the SetWindowText() in the thread or i i call PeekMessage in the WaitForSingleObject loop...this must have something to do with the message queue...
|
|
|
|
|
If this secondary thread's handle is closed while the wait is still pending, WaitForSingleObject() 's behavior is undefined.
Have you seen these two articles:
http://www.flounder.com/workerthreads.htm
http://www.flounder.com/uithreads.htm
|
|
|
|
|
One solution is a boolean variable to indicate the status of the loop.
Kuphryn
|
|
|
|
|
Aha!
m_cstaAnyStatic.SetWindowText causes a WM_SETTEXT message to be sent to the message queue. However, while in the loop in CAnyDlg::Stop, the UI thread can't process the message (this assumes that the static control and the dialog box were created by the same thread and hence share that thread's message queue).
You're effectively deadlocked.
It's typically a bad idea to directly modify any controls on the UI thread from a worker thread. It's better to define a custom message and post (not send) messages to the window to effect any changes in UI state. PostMessage just queues up the message, then returns; SendMessage blocks until the message is received by the window procedure, processed, and a response generated (either by returning from the window procedure, or by calling ReplyMessage ).
|
|
|
|
|
Good catch!! The post vs. send message problem is common, but is sometimes hidden in the problem description.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
Hi guys,
thanx for the hints! I will try the PostMessage()!
|
|
|
|
|
I execute an application in a console with ShellExecuteEx, but when this application ends I would the console's windows doesn't close because this function works like a daemon. So, how can I keep the window open?
thanks
|
|
|
|
|
chadell wrote:
...the console's windows doesn't close because this function works like a daemon. So, how can I keep the window open?
Maybe I'm reading this wrong, but first you say that the window doesn't close and then you say that you want to keep it open. Am I missing something?
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
sorry my english, david.
my problem is that the console application (executed by ShellExecuteEx) ends its execution and then closes its window, but the application needs to keep the window open until I close this(I thought to do this by the TerminateProcess with the hProcess returned by ShellExecuteEx). For more details, the application I want to run is MRTG.
thanks
|
|
|
|
|
One possible solution is to simply add a call to get() or another C++ I/O function that waits for the user to press ENTER before terminating.
Lookup ShellExecuteEx() at MSDN.
Kuphryn
|
|
|
|
|
A Visual Basic Application accessed a C++ DLL. That DLL must allocate a block of memory and populate it. It should then pass the pointer to the first elements back to VB for outputing the results.
Q: How can I free the memory from the VB once I am done? Is using functions such a GlobalFree or HeapFree the solutions? Are there any caveats, problems?
Currently I have space allocated in VB, the pointer is passed to C++, and then space deallocated in VB. The problem here is that I do not know beforehand the exact size of the array, and the "to be on the safe side" allocation is quite wasteful.
Please help.
Thank you
|
|
|
|
|
I guess the proper question here is what is Visual C++'s new operator equivalent to : GlobalAlloc, HeapAlloc, LocalAlloc, CoTaskMemAlloc, etc?
If I know that, then I can probably use the appropriate method to free memory in VB.
|
|
|
|
|
Why can't you write a function in the DLL that does the deletion?
My neighbours think I am crazy - but they don't know that I have a trampoline. All they see my head bobbing up and down over the fence every five seconds
|
|
|
|
|
Because I need to output results in VB from this array before I deallocate it.
|
|
|
|
|
JWood's suggestion still applies. You have one function in the C++ DLL that allocates the memory, and another function in that DLL that deallocates the same memory. After the memory has been allocated, but before it is deallocated, the VB code can use it.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
This is actually an interesting point. I haven't thought about doing this before. I guess the question then becomes: does calling the DLL twice create more overhead than allocating excess amount of memory in VB?
|
|
|
|
|
"Calling a DLL" is actually a misnomer. The overhead comes in loading the DLL into the address space of the process. Once that happens, a function call is a function call.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
Like the others, the new operator allocates memory, but it's the only one that, when operating on objects, calls their constructor. Trying to mix memory-management routines has no positive results.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|