Skip to content

Latest commit

 

History

History
42 lines (37 loc) · 5.69 KB

Lecture 13.md

File metadata and controls

42 lines (37 loc) · 5.69 KB


Еще про многопоточность

Promise + future

promise.set_value()
promise.set_exception()

future.get()

Promise - отдается потоку, который считает
Future - отдается потоку, которому требуется значение
Эта пара позволяет считать что-то в одном потоке, а получать в другом без нагромождения mutex и т.д.

Часто неприменимо, например .get() в UI потоке зафризит UI поток, подобные штуки сильно ограничивают применимость.

Packaged_task (некая обертка над promise)

Позволяет сделать:
T f() + promise<T> -> void g()

std::async

Принимает T f(), возвращает future<T>

Позволяет считать 2 способами: полностью асинхронно, либо лениво - можно не считать до вызова get()

Еще о потоках

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

Но почему cancellation не включить в std? Дело в том, что conditional variable и mutex реализованы через интерфейс ОС, поэтому они будут от поддержки замедляться. Поэтому обычно cancellation реализуют из вне, но отсюда возникает проблема, что когда ждешь conditional variable или mutex, то не отcancell’ишься.

Thread pool
Создавать все время потоки может быть не выгодно. Давайте тогда создадим какое-то количество потоков, удалять их не будем, а когда приходит новая задача будем отдавать ее в очередной из созданных потоков. Это концепция и называется thread pool. В std нет ничего такого.

Проблема в том, что потоки могут друг друга ждать, и это ожидание может быть в глубину в разы больше количества потоков, поэтому pool может встать в очередь просто.

Поэтому разные режимы async потенциально позволяют ему использовать полноценный thread pool.

TLS (thread local storage)
Глобальная переменная, но своя для каждого потока

STM (Software transactional memory)
Мы хотим что бы какой-то код был выполнен как единое целое
Если deadlock - откатить все и попробовать заново

Проблема - на практике все что реализовывали оказывалось медленным

HTM(Hardware transactional memory)
Аппаратная поддержка того же самого
Но тут много проблем с реализаций тоже (при неудаче транзакции надо много канселить, потом еще и mutex брать и в итоге все плохо), интел пытались но получилось не оч и не прижилось