Boost logo

Boost :

Subject: Re: [boost] [thread] 2 questions about thread interruption
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2016-04-20 18:30:55


Le 20/04/2016 08:52, Andrzej Krzemienski a écrit :
> 2016-04-19 20:36 GMT+02:00 Vicente J. Botet Escriba <
> vicente.botet_at_[hidden]>:
>
>> Le 18/04/2016 23:50, Andrzej Krzemienski a écrit :
>>
>>> 2016-04-18 23:42 GMT+02:00 Andrzej Krzemienski <akrzemi1_at_[hidden]>:
>>>
>>> Hi,
>>>> I have two questions connected to thread interruption in Boost.Thread.
>>>>
>>>> *1.* The docs say that interrupt_and_join_if_joinable is defined as
>>>> follows:
>>>>
>>>> ```
>>>> struct interrupt_and_join_if_joinable{
>>>>
>>>> void operator()(thread& t)
>>>> {
>>>> t.interrupt();
>>>> if (t.joinable())
>>>> {
>>>> t.join();
>>>> }
>>>> }};
>>>>
>>>> ```
>>>>
>>>> Sorry, let me continue with the question. Is there a reason why
>>> t.interrupt() is called without checking if t is joinable? This looks
>>> uncomfortable to me that I would be potentially calling interrupt() on a
>>> not-a-thread.
>>>
>> Interrupting a not-a-thread should do nothing. I will add this to the
>> reference documentation.
>> However nothing prevents to implement it this way
>>
>> void operator()(thread& t)
>> {
>> if (t.joinable())
>> {
>> t.interrupt();
>> t.join();
>> }
>> }};
>>
>> I will do it.
>>
>
> Hi Vicente, thanks for the reply.
>
>
>> *2.* When I make a call to this_thread::wait_for(),
>> Do you mean sleep_for here?
>>
> Yes :) sleep_for(). But in general, my concern applies to any operation
> that can potentially block.
>
>
>> blocking for a long
>>> time in thread t2, and the instant later I call t2.interrupt() from
>>> another
>>> thread t1. Do I have to wait the long time until wait_for() stops blocking
>>> t2, or does thread_interrupted get called 'immediately' after interrupt()
>>> is called from t1?
>>>
>> It depends. If sleep_for is implemented using
>> nanosleep()/pthread_delay_np() there is no way to throw the
>> thread_interrupted exception. However, if it is implemented waiting on a
>> condition variable wait_for, then the exception will be throw before the
>> duration elapses.
>>
>> Currently, sleep_for make use of nanosleep/pthread_delay_np when
>> available. The advantage been that the sleep is steady/monotonic.
>>
> So, I understand that this means that the interface (as opposed to the
> current or any future implementation) can only guarantee that in the worst
> case thread_interrupted is called *after* the operation unblocks the thread.
Right.
> Does the same guarantee apply to other blocking operations on mutex and or
> conditional variables?
No. For mutex and condition_variable timed operations the interruption
is throw as soon as interrupt is called. Only sleep make use of nonosleep.
>
>
>> *3.* Does the support for interruption points require the other
>>> synchronization operations (like locks on mutexes) to be slower (in order
>>> to monitor interruption requests)?
>>>
>> Not for locks and mutex, but yes it will be a little bit slower for
>> condition variables, as we need to store the condition variable on which a
>> thread could be waiting for.
>>
>> I've on my TODO list a task to build interuptible threads on top of raw
>> threads, but this will need to have also specific condition variables :(
>>
> Perhaps I owe you some background on these questions. I wanted to use
> boost::thread in place of std::thread in my job just because of this
> interruption mechanism that I would otherwise need to implement manually.
> But other colleagues raised concerns about what guarantees are really
> offered by the interruption mechanism.
I understand their concerns. Hoping the guaranties are clearer now. Let
me know if you want some additional clarifications.

Best,
Vicente


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk