Как прервать ожидающий поток C ++ 0x? - PullRequest
9 голосов
/ 17 мая 2010

Я рассматриваю использование потоков C ++ 0x в своем приложении вместо потоков Boost. Тем не менее, я не уверен, как переопределить то, что у меня есть, со стандартными потоками C ++ 0x, поскольку у них, похоже, нет метода interrupt().

Моя текущая настройка:

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

Рабочие вызывают wait() как минимум по двум различным условным переменным. Мастер имеет состояние «тайм-аут»: в этом случае он говорит всем работникам остановиться и дать любой результат, который они получат к тому времени. С потоками Boost мастер просто использует interrupt_all() в группе потоков, что заставляет работников перестать ждать. Если они не ждут в данный момент, мастер также устанавливает флаг bool, который периодически проверяют работники.

Однако в C ++ 0x std::thread я не вижу замены для interrupt(). Я что-то пропустил? Если нет, то как я могу реализовать вышеуказанную схему, чтобы работники не могли просто спать вечно?

Ответы [ 3 ]

9 голосов
/ 17 мая 2010

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

void th(Interruptor& interruptor) {
  try {

    ...

    while (cnd1.timed_wait(d)==false) {
      interruptor.check_interruption_point();
    }
    ...
  } catch (interrupted_exception &) {}
}

Класс Interruptor будет поддерживать булеву переменную, защищенную мьютексом или использующую атомарные операции, если они у вас есть, и две функции interrupt и check_interruption_point, которые выдают исключение interrupted_exception, если логическое значение true. Поток Mater создаст переменную Interruptor, которая будет передана заинтересованным потокам во время создания. Мастер имеет возможность прерывать сразу все потоки, которые зависят от этого прерывателя. Конечно, вы можете создать прерыватель для каждого потока, если хотите явно прерывать один поток за раз.

Вы сами можете определить продолжительность времени ожидания, чтобы ваши потоки могли реагировать, как только ваша программа требует.

1 голос
/ 12 декабря 2013

Действительно, C ++ 11 std :: thread не предлагает стандартного механизма для этого (пока?). Поэтому я второй @ doublep решил пока использовать boost :: thread.

Мы бы предпочли использовать C ++ 11 std :: средства. Но мы не хотим перестраивать усиление terminate(), дополненное условным изменением состояния, чтобы прервать сны и т. Д. Без причины. Создание такой инфраструктуры весело , и не так сложно, но непродуктивно и менее стандартно, чем использование boost.

Помогает, что boost :: thread и std :: thread настолько похожи, что мы чувствуем, что не рисуем себя в угол. (Мы ожидаем, что возможная миграция в std :: thread будет относительно простой, возможно, даже тривиальной.)

1 голос
/ 30 августа 2010

Ожидание повышения для прерывания () - это отправка notify_all при условии, что поток в данный момент заблокирован, а затем проверка, не было ли запрошено прерывание. Если прерывание было запрошено, оно выполняет бросок boost :: thread_interrupted. Вы можете написать свой собственный поток класс на основе std :: thread с механизмом.

...