$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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