Linux C++: возврат из основного () заставляют многопоточное приложение завершаться?

Этот вопрос кажется, что это - вероятно, дубликат, но я не мог найти тот. Если я пропустил предыдущий вопрос, извинения.

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

В C++ это, кажется, не имеет место - как только основной поток возвращается, процесс завершается с другими потоками, все еще работающими. Для моего текущего приложения это легко решено с приложением pthread_join() но я задаюсь вопросом, что вызывает это поведение. Этот компилятор (gcc) конкретен, pthreads конкретный, или вид поведения совместно используется через большинство/все платформы, для которых был реализован C++? Это поведение, настраивающееся в pthreads (я просмотрел pthread API в pthread_attr_*() функции и не видели ничего, что выглядело релевантным.)?

Абсолютно отдельный вопрос, но в то время как Вы здесь..., что было бы одно использование pthread_detatch() для?

10
задан Greg Howell 22 July 2010 в 02:58
поделиться

3 ответа

Да. В современном Linux (что более важно в новых версиях GNU libc) exit_group - это системный вызов, используемый при возврате из main, а не простой exit . exit_group описывается следующим образом:

Этот системный вызов эквивалентен exit (2) за исключением того, что он не завершается только вызывающий поток, но все потоки в вызывающем процессе группа потоков.

Стоит отметить, что в текущем стандарте C ++ не упоминаются потоки, поэтому такое поведение не зависит от C ++, а зависит от конкретной реализации. Тем не менее, каждая реализация, которую я лично видел, убивает все потоки при завершении основного потока.

РЕДАКТИРОВАТЬ: Также стоит отметить ответ Джонатана Леффлера, который указывает на то, что стандарт POSIX действительно определяет такое поведение, поэтому это, безусловно, нормально для приложения, использующего pthreads для своей потоковой передачи.

РЕДАКТИРОВАТЬ: Чтобы ответить на следующий вопрос о pthread_detach . Обычно это считается утечкой ресурсов, если вы не присоединяетесь к неотключенному потоку. Если у вас есть длительная задача, которую вам не нужно «ждать», и она просто «заканчивается, когда заканчивается», тогда вы должны отсоединить ее, которая не будет иметь утечки ресурсов, когда она завершится без соединения. На странице руководства сказано следующее:

Функция pthread_detach () отмечает поток, идентифицированный потоком как отдельно. Когда оторвавшаяся нить прекращается, его ресурсы автоматически возвращается в система без необходимости в другом поток для присоединения к завершенному нить.

Итак, быстрый и грязный ответ: «Когда вам все равно, когда он закончится, отсоедините его. Если другой поток заботится о том, когда он заканчивается, и должен ждать его завершения, то не беспокойтесь».

13
ответ дан 3 December 2019 в 16:28
поделиться

Да

Стандарт POSIX гласит:

§3.297 Завершение процесса

Существует два вида завершения процесса:

  1. Нормальное завершение происходит при возврате из main (), при запросе с помощью функций exit (), _exit () или _Exit (); или когда последний поток в процессе завершается возвратом из своей функции запуска, вызовом функции pthread_exit () или посредством отмены.

  2. Ненормальное завершение происходит по запросу функции abort () или при получении некоторых сигналов.

Применяется первое нормальное условие завершения. (Обратите внимание, что стандарт C ++ (1998, 2003) ничего не говорит о потоках.)


Относительно pthread_detach ()

Стандарт POSIX (снова) говорит:

Функция pthread_detach () должна указать реализации, что хранилище для потока потока может быть освобождено, когда этот поток завершается. Если поток не завершился, pthread_detach () не должен вызывать его завершение.

Обоснование гласит:

Функции pthread_join () или pthread_detach () в конечном итоге должны вызываться для каждого создаваемого потока, чтобы можно было освободить память, связанную с потоком.

Было высказано предположение, что в функции «отсоединения» нет необходимости; атрибута создания потока detachstate достаточно, поскольку поток никогда не должен быть динамически отсоединен. Однако необходимость возникает по крайней мере в двух случаях:

  1. В обработчике отмены для pthread_join () почти необходимо иметь функцию pthread_detach (), чтобы отсоединить поток, на котором ожидает pthread_join ().Без этого обработчик должен был бы выполнить еще один pthread_join (), чтобы попытаться отсоединить поток, что одновременно задержало бы обработку отмены на неограниченный период и представило бы новый вызов pthread_join (), который сам может нуждаться в отмене. обработчик. В этом случае практически необходима динамическая отсрочка.

  2. Чтобы отсоединить «начальный поток» (что может быть желательно в процессах, которые настраивают серверные потоки).

12
ответ дан 3 December 2019 в 16:28
поделиться

Это не является спецификой компилятора и представляет собой стандартное поведение; приложение завершается при выходе из main(), поэтому, если вы хотите предотвратить завершение приложения, вам нужно, чтобы main() блокировал выполнение до тех пор, пока все потоки не завершатся, что вы и делаете, объединяя эти потоки. Когда вы вызываете команду pthread_create, она выделяет ресурсы для этого потока. Ресурсы не будут деаллоцированы, пока вы не выполните pthread_join (который блокирует поток до его завершения) или pthread_detach (который заставляет поток автоматически освободить ресурсы при выходе из него). Вам следует использовать pthread_detach всякий раз, когда вы запускаете фоновый поток, который завершится, когда его задача будет выполнена и которого вам не нужно ждать.

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

0
ответ дан 3 December 2019 в 16:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: