Как завершить поток в C++11?



Мне не нужно правильно завершать поток или заставлять его реагировать на команду "завершить". Я заинтересован в том, чтобы принудительно завершить поток, используя чистый C++11.

514   4  

4 ответов:

  1. можно назвать std::terminate() из любого потока и потока, на который вы ссылаетесь, будут принудительно завершить.

  2. вы могли бы организовать для ~thread() для выполнения на объекте целевого потока, без вмешательства join(), ни detach() на этот объект. Это будет иметь тот же эффект, что и вариант 1.

  3. вы можете создать исключение, которое имеет деструктор, который вызывает исключение. А затем организовать для цели поток, чтобы бросить это исключение, когда оно должно быть принудительно прекращено. Самое сложное в этом-получить целевой поток, чтобы бросить это исключение.

варианты 1 и 2 не утечка внутрипроцессных ресурсов, но они заканчиваются каждый нить.

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

в C++11 нет портативного способа (что я знаю), чтобы некооперативно убить один поток в многопоточной программе (т. е. не убивая все потоки). Не было никакой мотивации для разработки такой функции.

A std::thread может иметь эту функцию-член:

native_handle_type native_handle();

вы можете использовать это для вызова зависящей от ОС функции, чтобы делать то, что вы хотите. Например, на ОС Apple, эта функция существует и native_handle_type это pthread_t. Если вы добьетесь успеха, вы, вероятно, утечка ресурсов.

ответ @ Howard Hinnant является правильным и комплексные. Но это может быть неправильно понято, если он читается слишком быстро, потому что std::terminate() (весь процесс) имеет то же имя, что и "завершение", которое имел в виду @AlexanderVX (1 поток).

резюме: "завершите 1 поток + принудительно (целевой поток не сотрудничает) + чистый C++11 = никак."

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

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

Многопроцессорность предполагает разбиение всей среды выполнения на множество полностью изолированных процессов, управляемых операционной системой. Процесс включает и изолирует выполнение состояния окружающей среды, включая локальную память процесса и данные внутри него, и все системные ресурсы, такие как файлы, сокеты, объекты синхронизации. Изоляция является критически важной характеристикой процесса, поскольку она ограничивает распространение разломов по границам процесса. Другими словами, ни один процесс не может повлиять на согласованность любого другого процесса в системе. То же самое верно и для поведения процесса, но в менее ограниченном и более размытом виде. В такой среде любой процесс может быть убит в любой "произвольный" момент, потому что, во-первых, каждый процесс изолирован, во-вторых, операционная система имеет полные знания обо всех ресурсах, используемых процессом, и может освободить их все без утечки, и, наконец, процесс будет убит ОС не в произвольный момент, а в количестве хорошо определенных точек, где состояние процесса хорошо известно.

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

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

советы по использованию зависящей от ОС функции для завершения потока C++:

  1. std::thread::native_handle() только можно получить допустимый собственный тип дескриптора потока перед вызовом join() или detach(). После этого, native_handle() возвращает 0 - pthread_cancel() будет coredump.

  2. для эффективного вызова функции завершения собственного потока(например,pthread_cancel), вам нужно сохранить собственный дескриптор перед вызовом std::thread::join() или std::thread::detach(). Так что ваш родной Терминатор всегда имеет действительный родной ручка для использования.

дополнительные пояснения см.:http://bo-yang.github.io/2017/11/19/cpp-kill-detached-thread .

Comments

    Ничего не найдено.