LINUX.ORG.RU

Как отвязаться от std::future, что бы не ждать завершения потока.

 , , ,


0

1

C++. Есть объект std::future на стэке, полученный от std::async(), функция завершается, и при возврате из функции деструктор объекта std::future ждёт, пока завершится, отслеживаемый им поток, что вызывает неприемлемые задержки. Как можно отвязать этот объект от потока, что бы при его уничтожении не ждать, когда завершится поток?

★★★

Последнее исправление: normann (всего исправлений: 1)

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

Очевидно же - надо просто завершить тот самый поток, каким-то образом подав ему сигнал что его результаты более не нужны. Ну и/или перейти на паттерн publisher/subscriber и отвязаться в этом месте от future.

no-dashi-v2 ★★
()
Ответ на: комментарий от no-dashi-v2

Завершение не во всех случаях допустимо, поток должен работать. Во вторых там уже используется сигнализация завершения, только на завершение требуется ВРЕМЯ, которое для вызывающего потока ждать неприемлемо.

normann ★★★
() автор топика

вообще-то футуры и асинки, это попытка «красиво» синхронный вызов функции заменить асинхронным.

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

то есть у вас какие-то архитектурные проблемы.

alysnix ★★★
()

Вообще постановка задачи очень странная. Что значит «неприемлемые задержки»? Задержки ровно такие сколько выполняется асинхронная операция результата которой ты ждёшь. Не ждать его ты не можешь, потому что даже если тебе не нужен сам результат, тебе нужно знать завершилась ли она успехом и освободить её ресурсы. Но ты можешь захотеть хочешь ждать его в другом месте, тогда просто передай туда футуру, она moveable. В какую-нибудь очередь положи, например, которую кто-то будет асинхронно разгребать.

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

Перетащи future выше по стеку, чтобы его деструктор не вызывался. Либо, если он тебе вообще не нужен, не сохраняй его. Либо вообще посмотри в сторону std::promise

XMs ★★★★★
()

А не проще ли будет тупо std::thread, безо всех этих многочисленных обёрток туманного назначения?

Просто у меня как раз открыты вкладки раз, два и т.п., ежедневно перед сном их перечитываю, но суть по-прежнему ускользает. Нагородили.

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

Нагородили.

packaged_task? норм штука, пихаешь в нее функтор, получаешь future, и отправляешь дальше в thread на выполнение.

тотже async, но future получаешь заранее!

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

Не ждать его ты не можешь, потому что даже если тебе не нужен сам результат, тебе нужно знать завершилась ли она успехом и освободить её ресурсы.

Не обязательно есть такая необходимость. Вполне актуальна задача по сигналу как можно быстрее завершиться. Важные данные в том потоке могут и не присутствовать, а дескрипторы и память ОС подчистит сама. Основной же поток в таком случае зачищает свои ресурсы и выходит, фоновый помирает сам, если не укладывается.

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

По теме: единственный рабочий вариант это thread + detach. На фьючах это сделать можно, но нужно очень внимательно читать cppreference. Я такое делал, но не помню детали, помню лишь что пришлось задействовать packaged_task, и что все это было настолько неочевидно даже с портянкой комментариев, что в итоге я предпочел обычный thread и detach.

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

Не обязательно есть такая необходимость. Вполне актуальна задача по сигналу как можно быстрее завершиться.

Если задача действительно формулируется так, то просто _exit.

Если всё таки речь о том что есть некоторые потоки которых не нужно ждать, то detach или _exit после ожидания тех потоков которые надо ждать - по сути это одно и то же. Но в любом случае это роспись в профнепригодности из-за лени или неумения сделать чистое завершение всех тредов, а это всегда возможно даже без портянки комментариев, достаточно атомарного флажка и не использовать сисколлы которые могут блочиться на неограниченное время.

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

_exit

Я что-то сказал про завершение работы программы?

Зачистка ресурсов ОС было написано к тому, что так можно делать для завершения, не теряя важных данных.

достаточно атомарного флажка

Ох уж эти диванные эксперты. «Атомарный флажок» требует кооперации, которую нельзя внедрить всюду.

и не использовать сисколлы которые могут блочиться на неограниченное время.

Это вообще пушка. Всего-то, проинспектировать все зависимости на предмет использования блокирующих сисколлов и переписать на неблокирующие, попутно внедрив «атомарный флажок».

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

Это вообще пушка. Всего-то, проинспектировать все зависимости на предмет использования блокирующих сисколлов и переписать на неблокирующие, попутно внедрив «атомарный флажок».

Я что-то сказал про неблокирующие? Я писал про таймауты. Зачем использовать зависимость не умеющую в таймауты? Вообще, назови-ка хотя бы 3 таких.

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

Нагородили.

там все просто. промайз - это просто канал(в терминах golang например) размером в 1 элемент некоего типа, или канал на 0 элементов.

сам канал находится в промайзе, публичные функции промайза, это функции, которыми можно в канал элемент положить, типа put_value.

а футура - это ссылка на промайз, через которую можно дергать функции этого канала типа get_value.

когда ты обьявляешь промайз - ты создаешь канал. когда берешь от него футуру - ты берешь ссылку на канал.

все от чего можно взять футуру имеют в себе скрытый промайз, например packed_task.

чтобы в канал положить надо иметь ссылку на промайз, чтобы прочитать - ссылку на футуру(что имеет сама ссылку на канал(промайз))

эту кухню можно легко и ручками реализовать в более гибком варианте, по сути такой промайз это структура с семафором и полем некоего типа… в поле пишут результат, и открывают семафор.

некую ценность это все имеет, но надо понимать, что создание промайза - это как минимум создание семафора.

alysnix ★★★
()