|
Boost : |
From: Phil Endecott (spam_from_boost_dev_at_[hidden])
Date: 2007-11-06 07:40:40
Anthony Williams wrote:
> The interruption points are:
>
> thread::join, thread::timed_join
> this_thread::sleep
> condition_variable::wait, condition_variable::timed_wait
> condition_variable_any::wait, condition_variable_any::timed_wait
> this_thread::interruption_point
Am I the only one who thinks that not having cancellation points at
blocking I/O makes this fairly useless? Perhaps I am! I'm curious to
hear about use-cases where Anthony or Preston's proposals are appropriate.
> "Preston A. Elder" <prez_at_[hidden]> writes:
>> Third, interruption should also apply to locks - which would in part
>> solve the above situation. The problem with this of course is that it is
>> less efficient to use a mutex/condition crafted to work with
>> interruptions at the lock level.
>
> Yes, and that's why it doesn't happen. All the interruption points are where
> the thread is waiting for some event (e.g. a condition to be notified, a
> thread to finish, or a time to elapse). Locks should only be held for a short
> period, so blocking for a lock should not be a long wait. I don't agree that
> it should be an interruption point.
I think I agree with Preston. Yes, many locks are only held for short
periods, but that's not the only way they can be used.
One possibility would be to make lock acquisition a cancellation point
iff that lock acquisition would block. This is straightforward with
the futex code that I posted, and would not slow down the fast
un-contended case.
As I proposed when I presented my mutex benchmark results, it may make
sense to offer different types of locks for applications with very low
probability of contention and for non-trivial probabilities of contention.
One application for cancellation is to cleanly kill off threads or
groups of threads when something goes wrong. For example, I may
observe no activity and assume that a deadlock has occurred. This
would require that lock-acquisition be a cancellation point.
>> If you want to continue to offer interruption (which, by the way, I fully
>> support!) - I believe it should be done one of two ways.
>>
>> 1) Use a signal on POSIX systems and find some equivalent mechanism on
>> other systems. This will then actually mean what the user thinks -
>> thread::interrupt() interrupts the thread, not just breaks out of a
>> condition if it happens to be in one.
>
> If a thread is waiting on a condition variable, a signal is not guaranteed to
> abort the wait:
>
> "If a signal is delivered to a thread waiting for a condition variable, upon
> return from the signal handler the thread resumes waiting for the condition
> variable as if it was not interrupted, or it shall return zero due to spurious
> wakeup."
I think that, even if this problem could be avoided, delivering a
signal to the right thread is very hard.
> The only way I know to ensure that the thread being interrupted wakes from the
> condition variable is to broadcast the condition variable. The alternative is
> that boost::condition_variable does not actually use a pthread_cond_t in the
> implementation, and I'm not keen on that idea at all.
Interesting; I was planning to look at implementing conditions,
bypassing the pthreads layer, as I did for my futex code. What have
you discovered that has put you off that idea?
>> 2) Move interruption to its own series of structures. Like I did, with
>> an interruptable_mutex. The advantage of this is twofold:
>> 1) It can be implemented in a non-platform specific manner, using
>> existing data structures, so you implement the interruptable version once
>> (utilizing boost::mutex and boost::condition) and you don't have to care
>> about the underlying platform. This means it doesn't require any OS
>> specific support.
>> 2) It works exactly as the user thinks. An interruptable_mutex can be
>> interrupted while blocked on something to do with it (meaning when trying
>> to acquire a lock on it, OR when waiting on a condition with it).
>
> I'm not keen on this approach, as it really does mean that the thread can only
> be interrupted at the defined points.
It's even further from being able to cancel at blocking I/O....
Can I suggest that we don't entirely forget about
3) use pthread_cancel
It has some disadvantages, but it's the only solution that offers
cancellation at blocking I/O.
Regards, Phil.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk