Spec-Zone.ru › Julia 0.7

Многопоточность

Этот экспериментальный интерфейс поддерживает возможности многопоточности Julia. Типы и функции, описанные здесь, могут (и, вероятно, будут) изменяться в будущем.

Base.Threads.threadidФункция

Threads.threadid()

Получить идентификатор текущей потока выполнения. У главного потока ID 1.

исходный код

Base.Threads.nthreadsФункция

Threads.nthreads()

Получить количество потоков, доступных для процесса Julia. Это верхняя граница включительно для threadid().

исходный код

Base.Threads.@threadsМакрос

Threads.@threads

Макрос для распараллеливания цикла for для выполнения с несколькими потоками. Он порождает nthreads() количество потоков, распределяет пространство итераций между ними и выполняет итерации параллельно. В конце цикла устанавливается барьер, который ожидает завершения всех потоков, и цикл возвращается.

исходный код

Base.Threads.AtomicТип

Threads.Atomic{T}

Содержит ссылку на объект типа T, гарантируя, что к нему обращаются атомарно, т.е. безопасно для нескольких потоков.

Только определенные «простые» типы могут использоваться атомарно, а именно примитивные булевы, целые и типы с плавающей точкой. Это Bool, Int8...Int128, UInt8...UInt128, и Float16...Float64.

Новые атомарные объекты могут быть созданы из значений, не являющихся атомарными; если ни один не указан, атомарный объект инициализируется нулём.

К атомарным объектам можно получить доступ, используя обозначение []:

Примеры

julia> x = Threads.Atomic{Int}(3)
Base.Threads.Atomic{Int64}(3)

julia> x[] = 1
1

julia> x[]
1

Атомарные операции используют префикс atomic_, такие как atomic_add!, atomic_xchg! и т.д.

исходный код

Base.Threads.atomic_cas!Функция

Threads.atomic_cas!(x::Atomic{T}, cmp::T, newval::T) where T

Атомарно сравнить и установить x

Атомарно сравнивает значение в x с cmp. Если они равны, запишите newval в x. В противном случае оставляет x без изменений. Возвращает старое значение в x. Сравнивая возвращенное значение с cmp (через ===) можно определить, было ли x изменено и теперь содержит новое значение newval.

Дополнительные сведения см. в инструкции LLVM cmpxchg.

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

Примеры

julia> x = Threads.Atomic{Int}(3)
Base.Threads.Atomic{Int64}(3)

julia> Threads.atomic_cas!(x, 4, 2);

julia> x
Base.Threads.Atomic{Int64}(3)

julia> Threads.atomic_cas!(x, 3, 2);

julia> x
Base.Threads.Atomic{Int64}(2)
исходный код

Base.Threads.atomic_xchg!Функция

Threads.atomic_xchg!(x::Atomic{T}, newval::T) where T

Атомарно обменивает значение в x

Атомарно меняет значение в x на newval. Возвращает старое значение.

Дополнительные сведения см. в инструкции LLVM atomicrmw xchg.

Примеры

julia> x = Threads.Atomic{Int}(3)
Base.Threads.Atomic{Int64}(3)

julia> Threads.atomic_xchg!(x, 2)
3

julia> x[]
2
исходный код

Base.Threads.atomic_add!Функция

Threads.atomic_add!(x::Atomic{T}, val::T) where T <: ArithmeticTypes

Атомарно добавить val к x

Выполняет x[] += val атомарно. Возвращает старое значение. Не определено для Atomic{Bool}.

Дополнительные сведения см. в инструкции LLVM atomicrmw add.

Примеры

julia> x = Threads.Atomic{Int}(3)
Base.Threads.Atomic{Int64}(3)

julia> Threads.atomic_add!(x, 2)
3

julia> x[]
5
исходный код

Base.Threads.atomic_sub!Функция

Threads.atomic_sub!(x::Atomic{T}, val::T) where T <: ArithmeticTypes

Атомарно вычесть val из x

Выполняет x[] -= val атомарно. Возвращает старое значение. Не определено для Atomic{Bool}.

Дополнительные сведения см. в инструкции LLVM atomicrmw sub.

Примеры

julia> x = Threads.Atomic{Int}(3)
Base.Threads.Atomic{Int64}(3)

julia> Threads.atomic_sub!(x, 2)
3

julia> x[]
1
исходный код

Base.Threads.atomic_and!Функция

Threads.atomic_and!(x::Atomic{T}, val::T) where T

Атомарно побитовое И x с val

Выполняет x[] &= val атомарно. Возвращает старое значение.

Дополнительные сведения см. в инструкции LLVM atomicrmw and.

Примеры

julia> x = Threads.Atomic{Int}(3)
Base.Threads.Atomic{Int64}(3)

julia> Threads.atomic_and!(x, 2)
3

julia> x[]
2
исходный код

Base.Threads.atomic_nand!Функция

Threads.atomic_nand!(x::Atomic{T}, val::T) where T

Атомарно побитовое НЕ-И (not-and) x с val

Выполняет x[] = ~(x[] & val) атомарно. Возвращает старое значение.

Дополнительные сведения см. в инструкции LLVM atomicrmw nand.

Примеры

julia> x = Threads.Atomic{Int}(3)
Base.Threads.Atomic{Int64}(3)

julia> Threads.atomic_nand!(x, 2)
3

julia> x[]
-3
исходный код

Base.Threads.atomic_or!Функция

Threads.atomic_or!(x::Atomic{T}, val::T) where T

Атомарно побитовое ИЛИ x с val

Выполняет x[] |= val атомарно. Возвращает старое значение.

Дополнительные сведения см. в инструкции LLVM atomicrmw or.

Примеры

julia> x = Threads.Atomic{Int}(5)
Base.Threads.Atomic{Int64}(5)

julia> Threads.atomic_or!(x, 7)
5

julia> x[]
7
исходный код

Base.Threads.atomic_xor!Функция

Threads.atomic_xor!(x::Atomic{T}, val::T) where T

Атомарно побитовое ИСКЛЮЧАЮЩЕЕ ИЛИ (exclusive-or) x с val

Выполняет x[] $= val атомарно. Возвращает старое значение.

Дополнительные сведения см. в инструкции LLVM atomicrmw xor.

Примеры

julia> x = Threads.Atomic{Int}(5)
Base.Threads.Atomic{Int64}(5)

julia> Threads.atomic_xor!(x, 7)
5

julia> x[]
2
исходный код

Base.Threads.atomic_max!Функция

Threads.atomic_max!(x::Atomic{T}, val::T) where T

Атомарно сохранить максимальное значение из x и val в x

Выполняет x[] = max(x[], val) атомарно. Возвращает старое значение.

Дополнительные сведения см. в инструкции LLVM atomicrmw max.

Примеры

julia> x = Threads.Atomic{Int}(5)
Base.Threads.Atomic{Int64}(5)

julia> Threads.atomic_max!(x, 7)
5

julia> x[]
7
исходный код

Base.Threads.atomic_min!Функция

Threads.atomic_min!(x::Atomic{T}, val::T) where T

Атомарно сохранить минимальное значение из x и val в x

Выполняет x[] = min(x[], val) атомарно. Возвращает старое значение.

Дополнительные сведения см. в инструкции LLVM atomicrmw min.

Примеры

julia> x = Threads.Atomic{Int}(7)
Base.Threads.Atomic{Int64}(7)

julia> Threads.atomic_min!(x, 5)
7

julia> x[]
5
исходный код

Base.Threads.atomic_fenceФункция

Threads.atomic_fence()

Вставка барьера последовательной согласованности памяти

Вставляет барьер памяти с семантикой последовательной согласованности. Существуют алгоритмы, где это необходимо, т.е. где порядок приобретения/освобождения недостаточен.

Вероятно, это очень дорогостоящая операция. Поскольку все другие атомарные операции в Julia уже имеют семантику приобретения/освобождения, явные барьеры в большинстве случаев не нужны.

Дополнительные сведения см. в инструкции LLVM fence.

исходный код

ccall с использованием пула потоков (Экспериментально)

Base.@threadcallМакрос

@threadcall((cfunc, clib), rettype, (argtypes...), argvals...)

Макрос @threadcall вызывается так же, как ccall, но выполняет работу в другом потоке. Это полезно, когда вы хотите вызвать блокирующую C-функцию, не заставляя основной julia поток блокироваться. Конкурентность ограничена размером пула потоков libuv, который по умолчанию равен 4 потокам, но может быть увеличен путем установки переменной среды UV_THREADPOOL_SIZE и перезапуска процесса julia.

Обратите внимание, что вызываемая функция не должна обращаться обратно в Julia.

исходный код

Примитивы синхронизации

Base.Threads.AbstractLockТип

AbstractLock

Абстрактный супертип, описывающий типы, реализующие потокобезопасные синхронизационные примитивы: lock, trylock, unlock и islocked.

исходный код

Base.lockФункция

lock(lock)

Получить lock, когда он станет доступным. Если блокировка уже захвачена другой задачей/потоком, дождаться её освобождения.

Каждая lock должна быть согласована с unlock.

исходный код

Base.unlockФункция

unlock(lock)

Освобождает владение lock.

Если это рекурсивная блокировка, которая была захвачена ранее, декрементирует внутренний счётчик и возвращает немедленно.

исходный код

Base.trylockФункция

trylock(lock) -> Success (Boolean)

Захватить блокировку, если она доступна, и вернуть true, если операция успешна. Если блокировка уже захвачена другой задачей/потоком, вернуть false.

Каждая успешная trylock должна быть согласована с unlock.

исходный код

Base.islockedФункция

islocked(lock) -> Status (Boolean)

Проверить, удерживается ли lock какой-либо задачей/потоком. Не следует использовать для синхронизации (используйте вместо этого trylock).

исходный код

Base.ReentrantLockТип

ReentrantLock()

Создаёт рекурсивную блокировку для синхронизации Taskов. Одна и та же задача может захватывать блокировку любое количество раз. Каждая lock должна быть согласована с unlock.

Эта блокировка НЕ потокобезопасна. См. Threads.Mutex для потокобезопасной блокировки.

исходный код

Base.Threads.MutexТип

Mutex()

Стандартные системные мьютексы для блокировки критических участков кода.

В Windows — это объект критической секции, в pthreads — это pthread_mutex_t.

См. также SpinLock для более лёгкой блокировки.

исходный код

Base.Threads.SpinLockТип

SpinLock()

Создаёт нерекурсивную блокировку. Рекурсивное использование приведёт к тупику. Каждая lock должна быть согласована с unlock.

Спин-блокировки типа «проверь-и-проверь-и-установи» самые быстрые при до 30-ти конкурирующих потоков. Если у вас больше контенции, возможно, блокировка — не лучший способ синхронизации.

См. также RecursiveSpinLock для версии, допускающей рекурсию.

См. также Mutex для более эффективной версии на одном ядре или если блокировка может удерживаться значительное время.

исходный код

Base.Threads.RecursiveSpinLockТип

RecursiveSpinLock()

Создаёт рекурсивную блокировку. Один и тот же поток может захватывать блокировку любое количество раз. Каждая lock должна быть согласована с unlock.

См. также SpinLock для немного более быстрой версии.

См. также Mutex для более эффективной версии на одном ядре или если блокировка может удерживаться значительное время.

исходный код

Base.SemaphoreТип

Semaphore(sem_size)

Создаёт счётный семафор, который позволяет максимум sem_size приобретений быть активными одновременно. Каждое приобретение должно быть согласовано с освобождением.

Этот конструкт НЕ потокобезопасен.

исходный код

Base.acquireФункция

acquire(s::Semaphore)

Дождаться, пока один из sem_size разрешений станет доступным, блокируясь, пока одно не будет приобретено.

исходный код

Base.releaseФункция

release(s::Semaphore)

Возвратить одно разрешение в пул, возможно, позволив другой задаче его получить и возобновить выполнение.

исходный код

© 2009–2019 Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and other contributors
Licensed under the MIT License.
https://docs.julialang.org/en/v0.7.0/base/multi-threading/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API