LINUX.ORG.RU

Вернуть результат thread в С++ без мутексов?

 ,


0

1

Можно так?

Логика - запускаю thread.detach(), который либо после проверок сразу завершается, если проверки пройдены встает на ожидание внешнего события (слушает на сокете порт), как только событие наступает делает некоторые действия и завершается - так вот из основного потока хотелось бы знать выполняется ли еще этот поток, если нет, то получить из него значение БЕЗ блокировки основного потока?

Показалось future с его async() подойдет, но оказалось valid() проверяет всего лишь был ли async() и не делали ли еще get(), а не отсутствие результата для get(), следовательно если поток не завершился get() блокирует основной поток.

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

★★★

Ответ на: комментарий от ox55ff

П.С. Пример с семафором просто как иллюстрация, что можно получать значение без блокировки, наверное атомик в этом плане шире, но надо разбираться )

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

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

Сишное конеш, но почему то функционал семафоров более гибкий.

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

подумай над циклом обработки событий, если хочешь в хоть какую-то эффективность

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

если это верно, то не получу ли я 100% загрузку ядра таким циклом?

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

Подскажите, вот этот участок кода в вашем примере, проверяющий значение атомика в цикле - правильно понимаю дает 100% загрузку ядра???

while (true) {
		if (mes[0]->f.test(memory_order_acquire))
			return mes[0]->data;
	}
wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 1)
Ответ на: комментарий от wolverin

Да. Это лишь для примера, если ждать нужно долго, то засыпать следует по-честному, с мьютексом, а не так топорно в цикле. Сценарий с атомиком - проверили, данные не готовы, побежали дальше что-то делать. Для такого сценария вряд ли существует более быстрый способ, ну если только использовать relaxed чтение, а после проходить через std::atomic_thread_fence, на каких-то архитектурах может быть какой-то выхлоп (но у меня нет никакой статистики и опыта на таком железе).

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

Не, активный сон это не всегда эффективно, особенно в руках тех, кто не до конца ещё раскрыл для себя потенциал механизмов на основе переключения контекста. Речь про event loop, цикл обработки событий, частные случаи реализации это: boost::asio::io_service или QEventLoop например. Рекомендую посмотреть сорцы, и проникнуться идеей.

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

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

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

) не, конеш уже страдаю амнезией, но к счастью не в этом случае.

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

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

Решил тут вникнуть глубже в ваш пример с atomic_flag f и оказалось, что f.test это C++20, далековато для меня получилось

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

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