[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Use of Thread::Cancel
From: |
Matt Scifo |
Subject: |
Re: Use of Thread::Cancel |
Date: |
Tue, 18 Nov 2003 09:32:08 -0800 |
David
I'm still a little sketchy on the use of cancellation points,
specifically using a yield or sleep call, something I prefer not to do
because performance time is a big factor in my requirements. Thank you
for the extended explanation of the cancellation concept. The detail
along with what I understood from reading the docs helped me to explain
the concept. It's just the implementation that still causes me
confusion.
Below I have amended my original example to make use of your example.
Please let me know if I am doing this right.
setCancel(cancelImmediate);
while(!stop_running)
{
if (!_module_queue->empty())
{
void *target;
// _module_queue is a class derived from Buffer.
// This call blocks until something has been posted
// to the queue.
//
// Do not cancel beyond this point until cancellation
// point has been reached!
_module_queue->wait(&target);
setCancel(cancelDeferred);
while(start_important_operations_with_target)
{
// do not process a cancel() request until this
// block finishes.
// after everything important finishes, do
// yield() or sleep()?
// i want this to have very little impact on the
// running time.
Thread::sleep(1); // sleep 1 microsecond
// this sleep call should tell the thread to cancel?
}
// set cancellation point here.
// cancel() can now take affect.
setCancel(cancelImmediate);
}
}
This also brought up a couple other concerns...
1) How exactly do I cancel a thread from another thread? There doesn't
seem to be a cancel() method. The terminate() method is available, but
only to parent objects as a protected method. I need to be able to stop
a thread from another thread that isn't the parent.
2) Will the thread process a request to stop it even though it is
blocking on a semaphore wait() call, part of the Buffer class?
Thanks again for your fast response.
Matt
On Mon, 2003-11-17 at 18:34, David Sugar wrote:
> "cancellation points" is a concept that exists in posix threading (pthreads).
>
> The idea is that specific calls or functions will act as a cancellation
> point, and these are defined typically as the sleep and yield call, a
> semaphore call, and a wait on a conditional object.
>
> Posix threads can be set to cancel either always, which may be bad, if, for
> example, a cancel request happens in the middle of an action that allocates
> or manipulates a system resource, at the stated cancellation points, or
> never. This is why cancellation points are useful, you can use them to make
> sure that at other times your thread will execute and operations will
> complete without interruption.
>
> Cancellation does not depend on a parent-child relationship because posix
> threads has no such concept, rather any thread can already join any other
> thread, unless a thread has been explicitly "detached", in which case no
> thread can cancel (join) it.
>
> Common C++ uses parent-child thread relationships as a convenience for thread
> death notification. That is, a Common C++ thread object is aware of the
> thread context of the thread it was created from. This could be useful for
> applications which wish to maintain such relationships, but in no way effects
> cancellation.
>
> Cancellation can be simulated in w32 with the addition of an additional
> object
> placed in artificially extended and alternate sleep, yield, and semaphore
> functions, and the w32 port of Common C++ does this to simulate posix
> behavior.
>
> Here is an example of a loop where setCancel may be used:
>
>
> for(;;)
> {
> failover();
> setCancel(cancelImmediate);
> time(&now);
> if(now >= last + refresh)
> {
> if(nodes > 1)
> elect();
> ... some other operations that may be interrupted
> }
>
> setCancel(cancelDeferred);
>
> // file operations are cancellation points...
> rtn = ::recvfrom(so, buffer, sizeof(node), 0,
> (struct sockaddr *)&addr, &alen);
> if(rtn < 1)
> {
> slog(Slog::levelWarning) << "network: input error..."
> << rtn << endl;
> // so is sleep
> Thread::sleep(5000);
> continue;
>
> The idea being you can use setCancel(cancelImmediate) to mark a section of
> code that you do not care if it is interrupted, such as a tight for loop that
> you dont want to waste a yield on but does not do any system operation.
>
>
>
> On Monday 17 November 2003 08:15 pm, Matt Scifo wrote:
> > Hello
> >
> > I am having some problems understanding exactly how to cancel a thread.
> >
> > I want to be able to issue a cancel request to a thread from another
> > thread (not a parent) and have it cancel only if it has not reached a
> > certain execution point. If that point has been reached, then the
> > cancel shouldn't be performed until a set point.
> >
> > The docs talk about using cancelDeferred and setting a cancellation
> > point "such as yield". I'm not quite sure how to set a specific
> > cancellation point.
> >
> > Here is some exmaple code that shows what I am trying to do...
> >
> > while(!stop_running)
> > {
> > if (!_module_queue->empty())
> > {
> > void *target;
> > // _module_queue is a class derived from Buffer.
> > // This call blocks until something has been posted
> > // to the queue.
> > //
> > // Do not cancel beyond this point until cancellation
> > // point has been reached!
> > _module_queue->wait(&target);
> >
> > while(start_important_operations_with_target)
> > {
> > // do not process a cancel() request until this
> > // block finishes.
> > }
> >
> > // set cancellation point here.
> > // cancel() can now take affect.
> > }
> > }
> >
> >
> > Can anyone offer any insight?
> >
> > I am using RH9, g++ 2.9.6, and commoncpp2 v1.0.13.
> >
> > Thanks
> >
> > Matt Scifo
> >
> >
> >
> > _______________________________________________
> > Bug-commoncpp mailing list
> > address@hidden
> > http://mail.gnu.org/mailman/listinfo/bug-commoncpp
>