How to wait for thread & if no response within time abort it
-
WaitForSingleObject() should do the trick. The first parameter will be the handle of your thread, and the second parameter will be the milliseconds to wait. WaitForSingleObject will return WAIT_OBJECT_0 if the thread terminates, or WAIT_TIMEOUT if the thread does not terminate in the specified time.
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03 "Obviously ??? You're definitely a superstar!!!" - mYkel - 21 Jun '04 "There's not enough blatant self-congratulatory backslapping in the world today..." - HumblePie - 21 Jun '05 Within you lies the power for good - Use it!
Thanks, thanks a lot for that info. I implemented it as follows. /////////////////////////////////////////////////////////// DWORD WINAPI WriteMdsDataPseudoThread( IN LPVOID vThreadParm ) { //Calling the member function in seperate thread. CDevice* pThreadParam = ( CDevice* ) vThreadParm; pThreadParam->write_mds_data_thread(); return 1; } unsigned short CDevice::write_mds_data(unsigned char *message ) { msg=message; ExecuteWriteThread();//call to start the thread return 1; } int CDevice::ExecuteWriteThread() { HANDLE hThread = NULL; DWORD dwThreadID = 0; int nTimeout = 1000; try { //Creating the thread hThread = CreateThread( NULL, // Pointer to thread security attributes 0, // Initial thread stack size, in bytes WriteMdsDataPseudoThread, this, // The argument for the new thread is a pointer to CDevice object 0, // Creation flags &dwThreadID ); // Pointer to returned thread identifier } catch( CException* /* pException */ ) { AfxMessageBox("Write Error. Please retry"); return false; } WaitForSingleObject(hThread, nTimeout); DWORD dwWaitReturn; GetExitCodeThread(hThread, &dwWaitReturn); if(STILL_ACTIVE == dwWaitReturn) CloseHandle(hThread); return 1; } /////////////////////////////////////////////////////////// but i am not sure, that the thread is terminated releasing all the resources. And my host application still hangs. can you help. Thanks again. Who is your hero? Only one who helps you, who cares about everyone problems.............Do you wanna be HERO?
-
Hello, I am new to VC++ and this forum too. i want to know how can I perform following task in VC++ 6 using MFC. I am writing host application and device drivers for a USB HID Device. I have a situation here, Whenever i call writreport function to write data to the USB HID device it has to Acknowledge. But buy any chance if device do not send back a response, the host software hangs( doesn't respond to user input). I thought of a solution for this, I will call the write report function in a thread and let thread wait for the ack from device. mean while the host application will wait for thread to complete for a specified time and if thread does not respond with in time then it(host) should shutdown the thread. Now I need your help here, the problem is I donot know how to implement it.( I just konw how to create a thread but have no idea how to wait for sometime and if no response exit the thread). thanks a lot for your time to read this. and thnaks for your help if you do so
Without knowing your exact problem I have a feeling that you should have another design session.:~ It seems to me like you are writing both the driver and some app that uses the driver and you have mixed up the responsabilities for a successful write operation between the two. I assume we are talking about a blocking call, otherwise I don't see the problem. The return value from the write operation in the driver should tell the caller whether the operation was successful or not. For the write operation to be successful an ACK is required from the device. Usually I tend to solve problems like this by having a thread that reads incoming data and maybe even interpret the data. In case of an ACK I would set an event that the write function waits for before returning with a call to WaitForSingleObject. The timeout should be reasonably short to be able to return as fast as possible, but yet long enough to give the device a chance to respond. In case of a timeout the write operation should return a value that informs the caller that the operation failed and why, if possible. If I'm wrong in my assumptions above, here's what you asked for:
if( ::WaitForSingleObject( hThread, 100 ) == WAIT_TIMEOUT )
{
::ExitThread( hThread );
}
::CloseHandle( hThread );Note that ::CloseHandle does not terminate the thread, you have to use ::ExitThread() for that and afterwards close all handles to the thread. Hope this helps -- Roger
-
Thanks, thanks a lot for that info. I implemented it as follows. /////////////////////////////////////////////////////////// DWORD WINAPI WriteMdsDataPseudoThread( IN LPVOID vThreadParm ) { //Calling the member function in seperate thread. CDevice* pThreadParam = ( CDevice* ) vThreadParm; pThreadParam->write_mds_data_thread(); return 1; } unsigned short CDevice::write_mds_data(unsigned char *message ) { msg=message; ExecuteWriteThread();//call to start the thread return 1; } int CDevice::ExecuteWriteThread() { HANDLE hThread = NULL; DWORD dwThreadID = 0; int nTimeout = 1000; try { //Creating the thread hThread = CreateThread( NULL, // Pointer to thread security attributes 0, // Initial thread stack size, in bytes WriteMdsDataPseudoThread, this, // The argument for the new thread is a pointer to CDevice object 0, // Creation flags &dwThreadID ); // Pointer to returned thread identifier } catch( CException* /* pException */ ) { AfxMessageBox("Write Error. Please retry"); return false; } WaitForSingleObject(hThread, nTimeout); DWORD dwWaitReturn; GetExitCodeThread(hThread, &dwWaitReturn); if(STILL_ACTIVE == dwWaitReturn) CloseHandle(hThread); return 1; } /////////////////////////////////////////////////////////// but i am not sure, that the thread is terminated releasing all the resources. And my host application still hangs. can you help. Thanks again. Who is your hero? Only one who helps you, who cares about everyone problems.............Do you wanna be HERO?
Hello... First, You use MFC then you should you use the Threading function from MFC like AfxBeginThread because some MFC internals need to prepared for Threading... When you use the pure API calls in the MFC it can produce unexpected situations and also Memory Leaks... Second, when you use the pure API then always closing the Thread Handle... Third, Use the Sleep function in your worker thread to enforce a context switch this can improve the performance of your app... Fourth... I believe you should read some more articels about threading before you continue your work... :) You can find the most important facts about threading here (especially for MFC) : http://www.codeproject.com/threads/usingworkerthreads.asp[^] Best regards...
-
Without knowing your exact problem I have a feeling that you should have another design session.:~ It seems to me like you are writing both the driver and some app that uses the driver and you have mixed up the responsabilities for a successful write operation between the two. I assume we are talking about a blocking call, otherwise I don't see the problem. The return value from the write operation in the driver should tell the caller whether the operation was successful or not. For the write operation to be successful an ACK is required from the device. Usually I tend to solve problems like this by having a thread that reads incoming data and maybe even interpret the data. In case of an ACK I would set an event that the write function waits for before returning with a call to WaitForSingleObject. The timeout should be reasonably short to be able to return as fast as possible, but yet long enough to give the device a chance to respond. In case of a timeout the write operation should return a value that informs the caller that the operation failed and why, if possible. If I'm wrong in my assumptions above, here's what you asked for:
if( ::WaitForSingleObject( hThread, 100 ) == WAIT_TIMEOUT )
{
::ExitThread( hThread );
}
::CloseHandle( hThread );Note that ::CloseHandle does not terminate the thread, you have to use ::ExitThread() for that and afterwards close all handles to the thread. Hope this helps -- Roger
Thanks for your time and reply, i tried ExitThread() Function. It gave me following error. error C2664: 'ExitThread' : cannot convert parameter 1 from 'void *' to 'unsigned long' And when i tried to use it as follows ::ExitThread(0); It sometimes exits the main application thread. I feel this happens when thread successfully executes and returns before the time out. Can i get some more info regarding this
-
Without knowing your exact problem I have a feeling that you should have another design session.:~ It seems to me like you are writing both the driver and some app that uses the driver and you have mixed up the responsabilities for a successful write operation between the two. I assume we are talking about a blocking call, otherwise I don't see the problem. The return value from the write operation in the driver should tell the caller whether the operation was successful or not. For the write operation to be successful an ACK is required from the device. Usually I tend to solve problems like this by having a thread that reads incoming data and maybe even interpret the data. In case of an ACK I would set an event that the write function waits for before returning with a call to WaitForSingleObject. The timeout should be reasonably short to be able to return as fast as possible, but yet long enough to give the device a chance to respond. In case of a timeout the write operation should return a value that informs the caller that the operation failed and why, if possible. If I'm wrong in my assumptions above, here's what you asked for:
if( ::WaitForSingleObject( hThread, 100 ) == WAIT_TIMEOUT )
{
::ExitThread( hThread );
}
::CloseHandle( hThread );Note that ::CloseHandle does not terminate the thread, you have to use ::ExitThread() for that and afterwards close all handles to the thread. Hope this helps -- Roger
Hello... Roger Stoltz wrote: if( ::WaitForSingleObject( hThread, 100 ) == WAIT_TIMEOUT ){ ::ExitThread( hThread );}::CloseHandle( hThread ); This is wrong, ExitThread must be always called from that thread which should be end... That means inside the worker thread... When you like to end a thread outside from worker thread then must use GetExitCodeThread and TerminateThread... But in the most situations it exists an better solution...
-
Hello... Roger Stoltz wrote: if( ::WaitForSingleObject( hThread, 100 ) == WAIT_TIMEOUT ){ ::ExitThread( hThread );}::CloseHandle( hThread ); This is wrong, ExitThread must be always called from that thread which should be end... That means inside the worker thread... When you like to end a thread outside from worker thread then must use GetExitCodeThread and TerminateThread... But in the most situations it exists an better solution...
your are right, i use the following code and it is working (still not tested vigorously) WaitForSingleObject(hThread, nTimeout); DWORD dwWaitReturn; GetExitCodeThread(hThread, &dwWaitReturn); if(STILL_ACTIVE == dwWaitReturn) { AfxMessageBox("Write Error. Please retry"); ExitThread( 0 ); CloseHandle(hThread); } I do not use TerminateThread() function as it doesn't deallocates resources allocated to the thread. and yes, i will use AfxBeginThread() to start my thread. Thanks for your Efforts
-
Hello... Roger Stoltz wrote: if( ::WaitForSingleObject( hThread, 100 ) == WAIT_TIMEOUT ){ ::ExitThread( hThread );}::CloseHandle( hThread ); This is wrong, ExitThread must be always called from that thread which should be end... That means inside the worker thread... When you like to end a thread outside from worker thread then must use GetExitCodeThread and TerminateThread... But in the most situations it exists an better solution...
HumanOsc wrote: This is wrong, ExitThread must be always called from that thread which should be end... That means inside the worker thread... Of course this is wrong! My mistake. I virtually never use these functions to end a thread, I consider it a design problem and always try to find another solution, like you suggested. I was too lazy to look up the name of the function I was looking for and mistook ::TerminateThread for ::ExitThread. Really sorry.:-O Calling ::ExitThread does just what it sounds like: it exits the calling thread, like the main thread if the call is made from it. However, the use of ::TerminateThread is not recommended since it too does what the name of the function sounds like: it terminates the thread in question. "Terminate" as in Arnold Schwarzenegger "Hasta la vista, baby!" without letting the system reclaim allocated resources such as critical sections, heap, loaded DLLs and so on. Due to the possible side effects of this function I always try to find another solution by refactoring. I still consider the original problem a design problem. -- Roger
-
HumanOsc wrote: This is wrong, ExitThread must be always called from that thread which should be end... That means inside the worker thread... Of course this is wrong! My mistake. I virtually never use these functions to end a thread, I consider it a design problem and always try to find another solution, like you suggested. I was too lazy to look up the name of the function I was looking for and mistook ::TerminateThread for ::ExitThread. Really sorry.:-O Calling ::ExitThread does just what it sounds like: it exits the calling thread, like the main thread if the call is made from it. However, the use of ::TerminateThread is not recommended since it too does what the name of the function sounds like: it terminates the thread in question. "Terminate" as in Arnold Schwarzenegger "Hasta la vista, baby!" without letting the system reclaim allocated resources such as critical sections, heap, loaded DLLs and so on. Due to the possible side effects of this function I always try to find another solution by refactoring. I still consider the original problem a design problem. -- Roger
Well, I am new to all this. When you said there design problem and explained it, i didn't understood much. Can you suggest me why it is a design problem, and How it should be designed to avoid the problems. thanks a lot.
-
Well, I am new to all this. When you said there design problem and explained it, i didn't understood much. Can you suggest me why it is a design problem, and How it should be designed to avoid the problems. thanks a lot.
Please note that the following are recommendations and suggestions due to how I interpret the problem and your solution. Why do I consider this a design problem? There are two ways of solving problems like this: 1. sequential (blocking calls, synchronous, one thread) 2. parallel (non-blocking calls, asynchronous, multiple threads) Whenever you are thinking "I start a thread here and wait for it to end" you are trying to solve a parallel problem in a sequential way or vice versa. This is bad design. Either you solve it in a sequential way by having a blocking call to your write function and when you have actually written the data it polls for an acknowledge before returning...or you solve it in a parallel way by having a thread polling for acknowledgements and set an event when such an ack has been received. In the latter case you will wait for the event to be signaled in your write function with ::WaitForSingleObject or similar. If the device doesn't respond within proper time your wait function will return WAIT_TIMEOUT and you know that the data was not written. You should select your timeout so that the user doesn't feel that the application has hung, e.g. < 1s. The whole idea with a worker thread is to perform a task in the background and signal the main thread when the job is done, either by setting an event that another thread may be waiting for or posting a message. If I have understood your problem correctly it all boils down to the fact that you want to write some data and to know if the data was properly written you are waiting for an acknowledge. I understand this as the core of your problem. As I understand it the ACK you are waiting for consists of data, i.e. to be able to know if you have received the ACK you have receive data. What I would do is have a thread that receives data and interprets it, at least to know if the data received is an ACK and if it is use ::SetEvent() to signal an event. In the write function I would write the data and then call ::WaitForSingleObject with the handle of the event mentioned above as input parameter. If ::WaitForSingleObject returns WAIT_TIMEOUT I can return FALSE, -1 or whatever to notify the caller that the operation failed. The receiving thread will be terminated when the connection to the device is closed. HumanOsc recommended you an article written by Joseph Newcomer about worker threads. Joe has written lots of stuff that is absolutely worth reading at his own site: http:
-
Thanks, thanks a lot for that info. I implemented it as follows. /////////////////////////////////////////////////////////// DWORD WINAPI WriteMdsDataPseudoThread( IN LPVOID vThreadParm ) { //Calling the member function in seperate thread. CDevice* pThreadParam = ( CDevice* ) vThreadParm; pThreadParam->write_mds_data_thread(); return 1; } unsigned short CDevice::write_mds_data(unsigned char *message ) { msg=message; ExecuteWriteThread();//call to start the thread return 1; } int CDevice::ExecuteWriteThread() { HANDLE hThread = NULL; DWORD dwThreadID = 0; int nTimeout = 1000; try { //Creating the thread hThread = CreateThread( NULL, // Pointer to thread security attributes 0, // Initial thread stack size, in bytes WriteMdsDataPseudoThread, this, // The argument for the new thread is a pointer to CDevice object 0, // Creation flags &dwThreadID ); // Pointer to returned thread identifier } catch( CException* /* pException */ ) { AfxMessageBox("Write Error. Please retry"); return false; } WaitForSingleObject(hThread, nTimeout); DWORD dwWaitReturn; GetExitCodeThread(hThread, &dwWaitReturn); if(STILL_ACTIVE == dwWaitReturn) CloseHandle(hThread); return 1; } /////////////////////////////////////////////////////////// but i am not sure, that the thread is terminated releasing all the resources. And my host application still hangs. can you help. Thanks again. Who is your hero? Only one who helps you, who cares about everyone problems.............Do you wanna be HERO?
If this is an MFC application, why are you using
CreateThread()
?
"One must learn from the bite of the fire to leave it alone." - Native American Proverb
-
If this is an MFC application, why are you using
CreateThread()
?
"One must learn from the bite of the fire to leave it alone." - Native American Proverb
DavidCrow wrote: why are you using CreateThread()? :doh: Then What .....
AfxBeginThread()
..."Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
cheers, Alok Gupta VC Forum Q&A :- I/ IV
-
DavidCrow wrote: why are you using CreateThread()? :doh: Then What .....
AfxBeginThread()
..."Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
cheers, Alok Gupta VC Forum Q&A :- I/ IV
ThatsAlok wrote: Then What ..... AfxBeginThread()... Correct. It does some MFC-specific things that
CreateThread()
will not. While it may appear thatCreateThread()
will work, I think it is an illusion at best.
"One must learn from the bite of the fire to leave it alone." - Native American Proverb