Эффективный выход из многопоточного приложения (особенности) - PullRequest
6 голосов
/ 01 декабря 2010

Я прочитал несколько источников о правильных методах передачи сообщения из потока во все остальные потоки для корректного выхода (каждый поток выполняет свою собственную процедуру выхода). Из них мне понравилась идея глобального атомарного логического значения, которое можно пометить из любого потока, и все остальные потоки проверяют этот флаг для выполнения процедуры выхода - когда все потоки объединены, основной поток может затем выйти из приложения. *

Чисто вычислительные потоки, вероятно, будут обрабатываться по-другому, верно?

Это эффективно и безопасно? Есть ли лучший способ сделать это?

Спасибо!

Ответы [ 2 ]

4 голосов
/ 01 декабря 2010

Я не фанат потоков, проверяющих логические (или другие) переменные состояния, чтобы знать, когда что делать, потому что это расточительно. Потоки должны были бы вращаться, постоянно проверяя переменную, чтобы увидеть, есть ли новые инструкции. Это сжигает процессор.

Лучший вариант - создать семафор или в Windows событие, и все потоки ожидают этого. Потоки могут находиться в спящем режиме, пока они не заняты, и не будут красть временные интервалы у других потоков, выполняющих реальную работу, просто для проверки переменной.

1 голос
/ 01 декабря 2010

В Windows я использую QueueUserAPC для вызова функции, которая выдает исключение, что приводит к чистому завершению потоков.

Я написал подробности в этом ответе здесь:

Как гарантировать быстрое завершение работы моего приложения win32?

Итак, вот что происходит:

Скажем, поток A хочет завершить поток B (а затем C, D, ...)

  • Поток A вызывает QueueUserAPC(), передавая дескриптор потоку B и адрес функции, которая выдаст исключение класса MyThreadExit.
  • Поток B работает нормально до тех пор, пока не вызовет что-то, что проверяет ожидаемые оповещения. Может быть WaitForSingleObjectEx, может SleepEx или что-то еще.
  • В этот момент поток B запускает функцию APC, переданную ранее, вызывая исключение в потоке B.
  • Все объекты, выделенные стеком, автоматически уничтожаются корректно, поскольку исключение заставляет поток B "разматывать" свой стек.
  • Функция внешнего потока потока B поймает исключение.
  • Теперь поток B завершается, возможно, сигнализируя потоку A, что это сделано.
...