Повышение прерывания в реализации наивного опроса

Я разработал простой поток опроса (используя Boost 1.39.0), который проверяет, был ли доступ к ресурсу данных в течение определенного периода времени, и очищает соединение, если нет. Соответствующий код может быть рассмотрен ниже.

Мои опасения двояки:

1) Целесообразно ли использовать прерывание во сне для безопасного закрытия потока? Будет ли прерывание ждать окончания сна или оно прервется немедленно? Вы можете видеть, что я ловлю исключение thread_interrupted только для того, чтобы избежать цикла while.

2) Расточительно ли использовать нить, которая проводит большую часть своего времени во сне? Есть ли лучший шаблон для реализации простого механизма опроса в стандартном C++?

boost::xtime xt;

while (1) {
    try {
        boost::xtime_get(&xt, boost::TIME_UTC);
        xt.sec += _sleep_secs;
        boost::thread::sleep(xt);
        //
        // logic to check resource access
        // etc.
    } 
    catch(boost::thread_interrupted const&) {
        return;
    }
}

2 ответа

1) Это должно быть безопасно, судя по реализации Boost boost::thread::interrupt() для потоков POSIX:

void thread::interrupt()
{
    detail::thread_data_ptr const local_thread_info=get_thread_info();
    if(local_thread_info)
    {
        lock_guard<mutex> lk(local_thread_info->data_mutex);
        local_thread_info->interrupt_requested=true;
        if(local_thread_info->current_cond)
        {
            BOOST_VERIFY(!pthread_cond_broadcast(local_thread_info->current_cond));
        }
    }
}

Они блокируют мьютекс, устанавливают для interrupt_requested значение true и транслируют по условной переменной. И поток сразу же проснется, если он спит в boost::thread::sleep(). И они не используют pthread_cancel в нем для того, чтобы отменить поток.

2) Я не думаю, что один поток является пустой тратой ресурсов, если мы говорим о таких операционных системах, как Windows, Linux или HP-UX. Это цитата в поддержку этого пункта:

Многие ОС также имеют проблемы с обработкой более чем нескольких сотен потоков. Если каждый поток получает 2 МБ стека (не редкое значение по умолчанию), у вас заканчивается виртуальная память со значением (2^30 / 2^21) = 512 потоков на 32-разрядной машине с виртуальной машиной, доступной для пользователя 1 ГБ (как, скажем, Линукс как обычно поставляется на x86)

,

Я думаю, что использование совершенно нормально, многие люди используют его (например, последовательность выключения, когда вам нужно закрыть потоки - вы будете прерывать () все, после чего они могут отключиться).

Что касается повышения, тем не менее, обязательно прочитайте документацию: в частности, только несколько инструкций являются "точками прерывания", что означает, что поток будет прерван и получит это исключение, только если вы прерветесь во время выполнения этой инструкции. Если поток делает что-то еще, прерывание будет получено только при вводе точки прерывания, что может произойти через некоторое время после запроса interruptв зависимости от того, что вы делаете в своей теме.

Я думаю, что это правда в любом случае, вот как я понимаю следующее:

поток будет прерван в следующий раз, когда он войдет в одну из предварительно определенных точек прерывания с включенным прерыванием, или если он в данный момент заблокирован при вызове в одну из предварительно определенных точек прерывания с включенным прерыванием.

из документации по теме Boost

Другие вопросы по тегам