Можно ли обратиться к одному стеку из двух потоков
Что проверяют
Различаете ли вы стек вызовов потока и структуру данных «стек», и понимаете ли, где в Swift появляется гонка данных. Следом просят сделать потокобезопасный стек или спрашивают, чем актор лучше очереди.
Как отвечать
Уточните, о каком стеке речь, и ответьте на оба смысла.
Стек вызовов у каждого потока свой: кадры функций, локальные переменные, адреса возврата. По документации Apple вторичному потоку по умолчанию выделяется 512 КБ, главному больше. Штатно поток к чужому стеку не обращается. Обход есть, например передать указатель из withUnsafeMutablePointer в другой поток, но это неопределённое поведение: кадр к тому моменту может исчезнуть. Важная тонкость: локальная var, захваченная замыканием, переезжает в кучу, и через неё два потока уже делят одну переменную. В Swift 6 изменение такой переменной из @Sendable замыкания компилятор не пропустит.
Стек как структура данных, например обёртка над Array с push и pop, из двух потоков без синхронизации ломается: Array не потокобезопасен, одновременная запись портит буфер и роняет приложение. Варианты защиты:
- последовательная
DispatchQueue: все операции идут через неё,popчерезsync, чтобы вернуть значение; - блокировка:
NSLockилиOSAllocatedUnfairLock(с iOS 16), короткая критическая секция вокруг операции; Mutexиз модуля Synchronization, доступен с iOS 18;actor: снаружи к состоянию не добраться безawait, лучший выбор для кода на Swift Concurrency.
Где спотыкаются
Отвечают «стек у каждого потока свой, значит проблем нет», хотя спрашивали про структуру данных. Уточняющий вопрос в начале экономит половину разговора.
Берут конкурентную очередь с барьером, как для кеша. Для стека почти каждая операция пишущая, включая pop, так что барьер ничего не даёт, а последовательная очередь проще.
Защищают push и pop по отдельности, но снаружи пишут if !isEmpty { pop() }. Между проверкой и снятием другой поток успевает забрать элемент, поэтому составные операции тоже должны быть атомарными. Thread Sanitizer в Xcode покажет такую гонку раньше пользователей.