Я новичок в многопоточности, и мне нужно получить полное представление о «соединении» и нужно ли мне присоединять все потоки в моем приложении? И как это работает с многопоточностью?
нет, вы можете отсоединить один поток, если хотите оставить его в покое.
Если вы запускаете поток, либо отсоединяете его, либо присоединяете его до завершения программы, в противном случае это неопределенное поведение.
Чтобы узнать, что поток должен быть отсоединен, вы должны задать себе вопрос: «Хочу ли я запустить поток после завершения основной функции программы?». Вот некоторые примеры:
Когда вы делаете File / New, вы создаете новый поток и отсоединяете его: поток будет закрыт, когда пользователь закроет документ. Здесь вы не нужно присоединиться к темам
Когда вы выполняете симуляцию по методу Монте-Карло, некоторые распределенные вычисления или какие-либо алгоритмы типа «разделяй и властвуй», вы запускаете все потоки, и вам нужно дождаться всех результатов, чтобы вы могли объединить их. Здесь вы явно необходимость присоединиться к ветке, прежде чем объединять результаты
Функция pthread_join () приостанавливает выполнение вызывающего потока
пока целевой поток не завершится, если целевой поток не имеет
уже расторгнут По возвращении из успешного вызова pthread_join ()
с ненулевым аргументом value_ptr, значение передается pthread_exit ()
завершающим потоком делается доступным в указанном месте
по значению_ptr. Когда pthread_join () успешно возвращается, цель
поток был прерван. Результаты нескольких одновременных звонков
для pthread_join () указание того же целевого потока не определено. Если
поток, вызывающий pthread_join (), отменяется, затем целевой поток
не будет оторван.
Так pthread_join делает две вещи:
Подождите, пока поток закончится.
Очистить любые ресурсы, связанные
с резьбой.
Это означает, что если вы выйдете из процесса без вызова pthread_join, тогда (2) будет сделано для вас операционной системой (хотя это не приведет к отмене потока уборка), и (1) не будет сделано.
Так нужно ли вам звонить pthread_join зависит, нужно ли вам (1) случиться.
Если вам не нужна нить для запуска, то вы можете также pthread_detach Это. Отсоединенный поток не может быть присоединен (поэтому вы не можете ждать его завершения), но его ресурсы освобождаются автоматически, если он завершается.
мне нужно присоединиться к каждой теме в моем приложении?
Не обязательно — зависит от вашего дизайна и ОС. Join () активно опасен в приложениях с графическим интерфейсом. Как правило, если вам не нужно знать или не беспокоиться о том, что один поток завершен из другого потока, вам не нужно присоединяться к нему.
Я очень стараюсь не присоединяться / ждать для каких-либо потоков вообще. Потоки пула, потоки времени жизни приложения и тому подобное часто не требуют какого-либо явного завершения — это зависит от ОС и того, принадлежат ли потоки или явно связаны с какими-либо ресурсами, которые требуют явного завершения / закрытия / чего бы то ни было.
Не присоединиться к теме, как не delete
вся память вам new
, Это может быть безвредным или вредной привычкой.
Поток, с которым вы не синхронизировались, находится в неизвестном состоянии выполнения. Если это поток записи файла, он может быть наполовину записан, после чего приложение завершает работу. Если это сетевой поток связи, он может быть на полпути через рукопожатие.
Недостатком присоединения к каждому потоку является то, что если один из них попал в плохое состояние и заблокирован, ваше приложение может зависнуть.
В общем, вы должны попытаться отправить сообщение своим выдающимся темам, чтобы они сказали выйти и очистить. Затем вы должны подождать немного времени, чтобы они закончили или иным образом ответить, что они могут умереть, а затем закрыть приложение. Теперь перед этим вы должны указать, что ваша программа больше не открыта для бизнеса — закрыть окна GUI, отвечать на запросы от других процессов, которые вы закрываете, и т. Д. — так что если это занимает больше времени, чем ожидалось, пользователь не беспокоится. Наконец, если дела идут не так хорошо — если потоки отказываются отвечать на ваш запрос о том, что они закрываются, а вы отказываетесь от них, — вам также следует регистрировать ошибки, чтобы вы могли исправить то, что может быть симптомом более серьезной проблемы.
В последний раз, когда рабочий поток неожиданно зависал, я изначально думал, что это проблема с отключением сети и ошибкой в коде тайм-аута. При более глубоком осмотре это было потому, что один из используемых объектов был delete
d до синхронизации выключения: неопределенное поведение, которое в результате выглядело как зависание в моих случаях воспроизведения. Если бы мы не присоединились тщательно, эту ошибку было бы сложнее отследить (теперь правильнее всего было бы использовать общий ресурс, который мы не могли удалить: но ошибки случаются).
Потоки могут быть присоединяемыми или отсоединенными. Отдельные темы не должны быть соединены. С другой стороны, если вы не присоединитесь к присоединяемому потоку, ваше приложение утечет некоторую память и некоторые структуры потоков. c ++ 11 std :: thread вызвал бы std :: terminate, если он не был отмечен как отсоединенный и объект потока вышел из области видимости без .join()
называется. Увидеть pthread_detach а также pthread_create. Это очень похоже на процессы. Когда ребенок выйдет, он останется зомби, а его создатель не будет звонить waitpid
, Резонансом такого поведения является то, что создатель потока и процесса может захотеть узнать код выхода.
Обновление: если pthread_create
вызывается с аргументом атрибута, равным NULL (используются атрибуты по умолчанию), будет создан присоединяемый поток. Чтобы создать отдельный поток, вы можете использовать атрибуты:
pthread_attr_t attrs;
pthread_attr_init(&attrs);
pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
pthread_create(thread, attrs, callback, arg);
Кроме того, вы можете сделать поток, который будет отсоединен, вызвав pthread_detach
на созданном. Если вы попытаетесь присоединиться к отдельной теме, pthread_join
вернусь EINVAL
код ошибки. glibc имеет непереносимое расширение pthread_getattr_np
что позволяет получить атрибуты запущенного потока. Таким образом, вы можете проверить, если нить отсоединена с pthread_attr_getdetachstate
,