boost::this_thread::interruption_point() не вызывает исключение boost::thread_interrupted&

Я хочу прервать поток, используя boost::thread interrupt(). У меня есть следующий код, который не вызывает исключение boost::thread_interrupted&:

int myClass::myFunction (arg1, arg2) try{
//some code here
    do {   
        boost::this_thread::interruption_point(); 
        //some other code here
    } while (counter != 20000); 
}catch (boost::thread_interrupted&) {
    cout << "interrupted" << endl;
}

Если я заменю boost::this_thread::interruption_point() на boost::this_thread::sleep( boost::posix_time::milliseconds(150)) исключение будет брошено, и прерывание будет работать как надо.

Может кто-нибудь объяснить, почему boost::this_thread::interruption_point() не выдает ожидаемое исключение?


person KoKa    schedule 29.09.2014    source источник
comment
вполне возможно, что с помощью boost::this_thread::interruption_point() вы уже вышли из цикла до вызова boost::thread::interrupt(). boost::this_thread::interruption_point() не блокируется ни на какое время, это просто контрольная точка, где поток может быть прерван, а 20000 — не очень большое количество итераций для проверки чего-то подобного, если только другой код не показан занимает значительное количество времени для завершения.   -  person diverscuba23    schedule 29.09.2014
comment
Привет, спасибо за ответ. Когда вызывается boost::thread::interrupt(), я все еще нахожусь в цикле, потому что я печатаю счетчик, а он еще не достиг 20000. Код после boost::this_thread::interruption_point(); долго и требует времени для завершения, поэтому мне нужно прерывать его в некоторых случаях.   -  person KoKa    schedule 30.09.2014
comment
Теперь я понимаю, что вы не можете поставить точку прерывания перед функцией, которая не возвращает значение, и ожидать, что прерывание остановит ее. После вызова прерывания в следующий раз, когда запускается точка прерывания, возникает исключение, верно?   -  person xinthose    schedule 02.04.2015
comment
Функция возвращается, моя ошибка не включает ее в предоставленный код.   -  person KoKa    schedule 02.04.2015


Ответы (1)


Как заметил комментатор, невозможно исключить простое состояние гонки (во многом зависит от вашей архитектуры и нагрузки на ЦП). Тот факт, что добавление явного сна «помогает», подчеркивает это.

У вас одноядерная система?

Вот простой самодостаточный пример на случай, если вы заметите, что делаете что-то по-другому. Посмотрите этот простой тестер:

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

struct myClass { 
    int myFunction(int arg1, int arg2);
};

int myClass::myFunction (int arg1, int arg2)
{
    int counter = 0;
    try
    {
        //some code here
        do {   
            boost::this_thread::interruption_point(); 
            //some other code here
            ++counter;
        } while (counter != 20000); 
    } catch (boost::thread_interrupted&) {
        std::cout << "interrupted" << std::endl;
    }
    return counter;
}

void treadf() {
    myClass x;
    std::cout << "Returned: " << x.myFunction(1,2) << "\n";
}

int main()
{
    boost::thread t(treadf);
    //t.interrupt(); // UNCOMMENT THIS LINE
    t.join();
}

Он печатает

Returned: 20000

Или, если вы раскомментируете строку с t.interrupt()

interrupted
Returned: 0

В моей системе i7. Смотрите Прямой эфир на Coliru

person sehe    schedule 29.09.2014
comment
Привет и спасибо за ваш ответ. Я работаю на двухъядерной системе. Я прочитал приведенный вами пример, но не вижу никакой разницы между этим и моим кодом. - person KoKa; 30.09.2014
comment
Я полагаю, вы могли бы опубликовать SSCCE, который покажет вам проблему. Может быть, мы сможем что-то заметить - person sehe; 30.09.2014