Прерывание boost :: thread при отключенных прерываниях

При использовании boost :: thread я столкнулся с этой проблемой прерывания. Когда я делаю boost :: thread_interrupt из потока A в потоке B, а в B отключены прерывания (boost :: this_thread :: disable_interrupts di), прерывание кажется потерянным. То есть, если я помещаю boost :: thread :: interruption_point () после того, как прерывание было разрешено, оно не генерирует исключение boost :: thread_interrupted.

Это ожидаемое поведение или я что-то делаю не так?

Спасибо


person TomM    schedule 02.03.2011    source источник


Ответы (1)


Ничего в документации не говорится, что прерывания повторно запускаются, когда поток B повторно включает прерывания. Я попробовал простую тестовую программу и могу подтвердить описанное вами поведение.

После повторного включения прерываний вы можете проверить this_thread::interruption_requested(), было ли запрошено прерывание, когда прерывания были отключены. Если действительно было запрошено прерывание, вы можете сами выбросить thread_interrupted исключение.

Вот рабочая программа, которая демонстрирует это:

#include <boost/thread.hpp>
#include <iostream>

using namespace std;
using namespace boost;

void threadB()
{
    int ticks = 0;
    this_thread::disable_interruption* disabler = 0;
    try
    {
        while (ticks < 20)
        {
            if (ticks == 5)
            {
                cout << "Disabling interruptions\n";
                disabler = new this_thread::disable_interruption;
            }
            if (ticks == 15)
            {
                cout << "Re-enabling interruptions\n";
                delete disabler;
                if (this_thread::interruption_requested())
                {
                    cout << "Interrupt requested while disabled\n";
                    throw thread_interrupted();
                }
            }
            cout << "Tick " << ticks << "\n";
            thread::sleep(get_system_time() + posix_time::milliseconds(100));
            ++ticks;
        }
    }
    catch (thread_interrupted)
    {
        cout << "Interrupted\n";
    }
}

int main()
{
    thread b(&threadB);
    thread::sleep(get_system_time() + posix_time::milliseconds(1000));
    b.interrupt();
    cout << "main -> Interrupt!\n";
    b.join();
}

Надеюсь это поможет.

person Emile Cormier    schedule 02.03.2011
comment
Я должен сказать, что boost::thread становится довольно гладко! Раньше мне приходилось вручную реализовывать собственный механизм прерывания с помощью логической переменной, защищенной мьютексом. - person Emile Cormier; 02.03.2011