LINUX.ORG.RU

Прервать C++ поток

 ,


0

3

Пусть имеется класс, выполняющий запуск некоторой работы в потоке:

void MyThread::run() {
  if (!ThreadPtr) {
    ThreadPtr  = new std::thread(&MyThread::realWork, this);
    ThreadPtr->detach();
  }
}

При этом при этом realWork содержит вызов некоторой долгоработающей функции из сторонней библиотеки

MyThread::realWork(){ hardlib.hardWork(); ...}

Как можно прервать запущенный поток? Корректно ли просто сделать delete?

void MyThread::break() {
  if (ThreadPtr) {
    delete ThreadPtr;
    ThreadPtr=null;
  }

}

В с++ нет такого API, используй pthread или, лучше, отдельный процесс.

filosofia
()

Послать ему сообщение, чтобы он сам завершился корректно. Все остальное ошибка.

Ну либо использовать процессы, тогда ОС уберёт оставленный мусор.

invy ★★★★★
()
Последнее исправление: invy (всего исправлений: 1)
Ответ на: комментарий от invy

Да, обычно сторонней библиотекой оказывается какая-то внутренняя поделка, которую можно научить прерываться. Для остальных случаев есть fork.

filosofia
()
Ответ на: комментарий от invy

Послать ему сообщение, чтобы он сам завершился корректно. Все остальное ошибка

+1

yoghurt ★★★★★
()

Кажись и вправду нет такого API в самом С++. На Linux’е можно юзать pthread_cancel, предварительно вызвав std::thread::native_handle.

Nibbler
()

you are doing it wrong. Поток должен завершится без внешнего API. По сообщению/флагу/… за pthread_cancel как способ «штатного» завершения тоже надо бить ногами.

anonymous
()

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

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от Nibbler

Кажись и вправду нет такого API в самом С++.

И в портабельном glib тоже нет, что намекает на неоправданно большое количество подводных камней такого подхода.

gag ★★★★★
()
Ответ на: комментарий от slackwarrior

Using threads for performance reasons is an AntiPattern. At least when done without significant profiling which identifies serialization as a bottleneck.

Дальше не читал. Бред синьор энтерпрайз жаба кодера, который делает только CRUD и других задач и не видел никогда.

CatsCantFly
()
Ответ на: комментарий от CatsCantFly

Плохо ты читал. Там как раз про то, что джава тоже не нужна для параллелизма. И еще про массовое заблуждение «что потоки — это ускорение». Про закон Амдала тоже не все слышали, кто слышал что «прерывать поток — это антипаттерн» :)

slackwarrior ★★★★★
()
Последнее исправление: slackwarrior (всего исправлений: 2)

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

anonymous
()

точки отмены/прерывания пока не стандартизированный, поэтому на чистом c++ никак не влезая в логику функции потока.

pon4ik ★★★★★
()
Ответ на: комментарий от Reset

То то в POSIX про это столько фишечек.

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

Например дескриптор не поддерживает неблокирующий режим, а как-то по таймауту его i/o таки надо прервать.

pon4ik ★★★★★
()
Ответ на: комментарий от pon4ik

То то в POSIX про это столько фишечек.

И что? Половина POSIX’а состоит из костылей и подпорок.

Например дескриптор не поддерживает неблокирующий режим, а как-то по таймауту его i/o таки надо прервать.

Что за дескриптор? Откуда взялся? Почему не поддерживает?

Reset ★★★★★
()
Ответ на: комментарий от anonymous

за pthread_cancel как способ «штатного» завершения тоже надо бить ногами.

Объясни безграмотному, почему. Только без токсичности.

Nibbler
()
Ответ на: комментарий от CatsCantFly

Дальше не читал. Бред синьор энтерпрайз жаба кодера, который делает только CRUD и других задач и не видел никогда.

Да ваще лох! В 2020 увеличение производительности даже дисков/сети идёт почти линейное до 8-16, а то и больше тасков. А ещё полезно разбивать куски большого кода на поменьше, чтобы они в L2 хотя бы влазили, и собирать из них конвейер. Чувак высокопроизводительный код просто не писал никогда.

mv ★★★★★
()
Ответ на: комментарий от mv

Вы там все между строк пронзаете, нелохи, и читаете поверхам: At least when done without significant profiling which identifies serialization as a bottleneck. Типичное «искажение подтверждения». Потоки нифига не серебряная пуля, хоть в 2020-м, хоть когда. А «кэшфрендлинесс» с влезанием в L2 и прочая «локалити» тут ортогональна – против нее никто не возражает. Алсо, там перечисляются N точек зрения с «за» и «против» многопоточности, которой надо находить оправлание в конкретных задачах.

Чувак высокопроизводительный код просто не писал никогда.

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

anonymous
()
Ответ на: комментарий от anonymous

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

mv ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.