15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Killing a worker thread

Kalyan -- chakri@sunserv.cmc.stph.net
Thursday, October 10, 1996

Environment : Win95, VC++ 4.1

Hi all,

    I have created a worker thread in my application and depending
    on some status/criteria I would like to kill the thread at any
    point of time. To do that one has to setup a communication between
    the threads (worker and main application thread). If the communication
    is setup using the CEvent objects, the worker thread has to wait for 
    the event to happen and then can return from the controlling function.
    But my requirement is to kill the thread at any point of time. Please
    suggest me any ideas about this scenario.

Thanx in advance,
Kalyan.V
---------------------------------------------------------------
 Kalyana Chakravarthy.V   Ph  : +91-040-259401/259501      
 Engineer (R&D),          Fax : +91-040-259509
 CMC Limited,					
 Hyderabad, A.P.,         Email : chakri@hp735.cmc.stph.net
 INDIA.			          chakri@sunserv.cmc.stph.net
---------------------------------------------------------------



Vikas Patel -- vjp@wgw.safco.com
Friday, October 11, 1996

[Mini-digest: 9 responses]

Use Win32 API

The TerminateThread function terminates a thread.
BOOL TerminateThread(
    HANDLE hThread, // handle to the thread
    DWORD dwExitCode     // exit code for the thread
   );     

The hThread parameter is the handle of the worker thread which can be 
accessed by storing the m_hThread member of CWinThread instance of your 
worker thread. Also refer to the documentation of the TerminateThread API 
for operating system specific details.

/Vikas Patel

vjp@safco.com

 ----------
From: owner-mfc-l
To: mfc-l
Subject: Killing a worker thread
Date: Thursday, October 10, 1996 1:17PM

Environment : Win95, VC++ 4.1

Hi all,

    I have created a worker thread in my application and depending
    on some status/criteria I would like to kill the thread at any
    point of time. To do that one has to setup a communication between
    the threads (worker and main application thread). If the communication
    is setup using the CEvent objects, the worker thread has to wait for
    the event to happen and then can return from the controlling function.
    But my requirement is to kill the thread at any point of time. Please
    suggest me any ideas about this scenario.

Thanx in advance,
Kalyan.V
 ---------------------------------------------------------------
 Kalyana Chakravarthy.V   Ph  : +91-040-259401/259501
 Engineer (R&D),          Fax : +91-040-259509
 CMC Limited,
 Hyderabad, A.P.,         Email : chakri@hp735.cmc.stph.net
 INDIA.                           chakri@sunserv.cmc.stph.net
 ---------------------------------------------------------------
-----From: Mats Manhav 

Kalyan,

It sounds to me like you will have to check the signal at any point of time,
i.e quite often.

Instad of make of using a CEvent you could use a CMutex. In your main
application construct a CMutex object and CSingleLock object on the CMutex
object. Let the main application lock the mutex as long as the 
thread should be running. The worker should have accessibility to the CMutex
object somehow . Let the worker thread creates a CSingleLock on the CMutex
as well. It should not try to lock the Mutex.

The worker thread instead use the IsLocked member of the CSingleLock
function to check if it is time to
stop.

Mats

Some sample code: // simplified to show the scenario //
Somewhere_in_your_main_app()
{
   CMutex m_Mutex;	
   CSingleLock m_KeepOn(&m_Mutex, TRUE);  //lock the mutex
   
   // make the mutex visible to the worker thread somehow and start the
thread
   AfxBeginThread();
}

inline BOOL keep_on(CSingleLock *Lock)
{
   return !Lock->IsLocked();
}

worker_Thread()
{
   CSingleLock Lock(m_pMutex, FALSE);  // not locked

   // loop around the work thread and ckeck each time
   while (keep_on(&Lock))
   {
   }

   // or call keep_on() as many times you like and at any place you like
using if
   if (!keep_on(&Lock)
      // ExitTheThreadNicely
      goto exit_thread;

exit_thread:
   clean_up();
}

Mats

--
==========================================================================
Mats Mеnhav (Mats Manhav for 7-bit people)
email:manhav@connectum.skurup.se   WWW: http://connectum.skurup.se/~manhav
FAX:  (int) 46 (0) 414 243 05      Phone: (int) 46 (0) 414 243 05         
==========================================================================

-----From: Gabriel Parlea-Visalon 

The best thing to do first, is to make sure that none of the other 
synchronisation methods, mutexes, critical sections, semaphores, threads, etc 
can do the job.

If you still want to proceed, call DuplicateHandle() for the thread to be 
killed, from within the process that owns it, make sure the thread is still 
alive before doing that, pass it to the appropriate thread, call 
TerminateThread() on the passed handle.

Bear in mind that the target thread resides in memory until no other copies of 
its handle exist, its stack is not deallocated, no attached DLLS are notified of 
its termination either, etc.

It would be a very good idea to read more on the subject before attempting this, 
starting with the WIN32 SDK entry on TerminateThread().

I hope this will help you,

Gabriel

-- 
                             Gabriel Parlea-Visalon
                               Software Engineer
                           Derivative Trading Systems
                           gabriel@derivs.demon.co.uk

-----From: "Frank McGeough" 

The basic assumption you should enter into when programming threads 
is that you should always set up some method of communicating to 
the thread that you wish to terminate. Think of a regular old Windows 
program, would you rather get a WM_CLOSE message and shut down 
gracefully or would you rather have someone turn the machine off to 
close your program? (possibly while you are in the middle of saving 
a file?). 

Why should you cancel the execution of the running thread at
predicatable locations in the application code? If you kill a thread
arbitrarily, it may hold a Mutex that would result in a unrecoverable
deadlock situation. Even if you're not using Mutex's your run-time
library or some other library may use them. If the thread performs
file operations then you leave yourself with untestable restartability
problems because you have to assume that the thread can exit
at any point in the code. 

So what you need is to have the thread that is attempting to cancel
the thread use an Cancellation model. The requesting thread would
issue a RequestCancellation, and the running threads would call 
ServiceCancellation at various predictable places in the execution of
the code (for example, in a database application you might check
after each transaction is committed). If there are no Cancellations
waiting then the thread would just continue on its way. If there is
a Cancellation then the thread could possibly throw an exception
that would predicatably call all the right destructors for the objects
in your thread and exit. 

There are a number of good books out on programming with threads.
Here is one that you might like to check out.

Threads Primer: A Guide to Multithreaded Programming, Bill
Lewis and Daniel Berg, Sunsoft Press.

Good luck.
-----From: "Doug Boone" 

Does your worker thread have a message pump? Then send it a message and
tell it to die.

If not, you could have it wait for a semaphore and then release it right
away. When you want the worker thread to go away just get the semaphore and
then when the worker thread does its WaitFor*Object() on the semaphore it
will get a time-out message error code and know that it should terminate. 
 
We commonly just have a Boolean called "m_bKeepRunning" that someone turns
off to tell the worker threads to exit.
  
Two interesting problems we had early on were that 1) we didn't wait for
the thread to exit so we created memory leaks and 2) low priority threads
needed to be boosted so they could finish their clean-up in a reasonable
amount of time.

-----From: Mike Blaszczak 

At 13:17 10/10/96 IST, Kalyan  wrote:
>Environment : Win95, VC++ 4.1

>    I have created a worker thread in my application and depending
>    on some status/criteria I would like to kill the thread at any
>    point of time. To do that one has to setup a communication between
>    the threads (worker and main application thread).

Yep.

> If the communication
> is setup using the CEvent objects, the worker thread has to wait for 
> the event to happen and then can return from the controlling function.

It doesn't have to wait: it can simply check the status of the CEvent object
without waiting.  If it's set, it can bail out.  If it isn't set, it can
keep going.

>    But my requirement is to kill the thread at any point of time. Please
>    suggest me any ideas about this scenario.

You can't: asynchronously killing a thread is sloppy and bad.  Presumably,
your worker thread is in some loop doing some work anyway--so that loop
should be coded to exit when whatever conditions it needs are met, _OR_
when the event becomes signalled.  If you have lots of loops, you'll have
to either implement checks in each so that they're all capable of exiting
or write a state machine that manages the looping in one central place for
you and also checks the event.

Back in your main thread, when you shut things down, you should probably
do something like:

        m_pEvent->SetEvent();   // signal that we want to die
        WaitForSingleObject(m_pThread, INFINITE);    // wait for the worker

Maybe you could also add a priority boost to the worker thread so that
it, relative to the stopped controlling thread, finishes with great haste.
You could do that with CWinThread::SetThreadPriority().


.B ekiM
http://www.nwlink.com/~mikeblas/
Don't look at my hands: look at my _shoulders_!
These words are my own. I do not speak on behalf of Microsoft.

-----From: Noel Burton-Krahn 

(resisting urge to rant about Win32's brain-damaged thread 
implementation...)

There is no way to kill a thread cleanly from another.  I handle this 
problem by creating some state in my program indicating that the thread 
should terminate and the ignore the thread and let it commit suicide.  By 
"creating some state" I mean either:
1) Denying the thread access to a resource it needs
2) Posting a message to the thread
3) Setting an event.

Posting WM_QUIT or something like that to a thread is nice since it can 
either be synchronous or a synchronous.  Remember, though: don't trust 
PostThreadMessage if your target thread ever causes a window to be 
displayed (even indirectly!)

--Noel

-----From: "Vaitheeswaran, Venkat (NJAOST)" 

	I have the same problem. 
	I had to slice the worker thread to keep polling to know whether 
	a request to kill the thread has been made. Depending upon the
	nature of your worker thread, you may be able to slice it generously
	and/or at important points.

-----From: Steve Mark 

This may or may not help: If you're looping in the thread you can put a
timeout on the CEvent check so that it returns immediately after
checking the CEvent.  You can then check the return code/lock status to
determine if the CEvent was set.  That way you can check during
processing in the thread whenever you want and cleanup and exit when
the CEvent is set.  If you find a way to kill a thread external to the
thread itself, the thread will not be able to cleanup, close files,
release memory, etc.

_________________________________________________________________

Steven Mark                           E-mail: steve@otms.com

On-The-Mark Systems                   Tel:    510.648.9514

3494 Camino Tassajara Rd., Suite 239  Fax:    510.648.9507

Danville, CA 94506                    Web:    http://www.otms.com


     Custom Software Analysis, Design, and Implementation



Noel Burton-Krahn -- noel@harleystreet.com
Tuesday, October 15, 1996

TerminateThread is a little too scary to use. It doesn't even deallocate 
the stack of the terminated thread  Here's an excerpt from the docs:

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:


----------
From: 	Vikas Patel[SMTP:vjp@wgw.safco.com]
Sent: 	Friday, October 11, 1996 6:02 AM
To: 	MFCResp
Subject: 	RE: Killing a worker thread

[Mini-digest: 9 responses]

Use Win32 API

The TerminateThread function terminates a thread.
BOOL TerminateThread(
    HANDLE hThread, // handle to the thread
    DWORD dwExitCode     // exit code for the thread
   );

The hThread parameter is the handle of the worker thread which can be
accessed by storing the m_hThread member of CWinThread instance of your
worker thread. Also refer to the documentation of the TerminateThread API
for operating system specific details.

/Vikas Patel

vjp@safco.com








| Вернуться в корень Архива |