Spec-Zone.ru › Julia 1.1

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

Этот экспериментальный интерфейс поддерживает возможности многопоточности 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

Атомарно побитовое НЕ-И 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

Атомарно побитовое XOR (исключающее ИЛИ) 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.

Замки spin-lock типа «проверка-и-замена-и-проверка» самые быстрые до примерно 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/v1.1.1/base/multi-threading/

Spec-Zone.ru

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