SlideShare ist ein Scribd-Unternehmen logo
1 von 31
Downloaden Sie, um offline zu lesen
Примитивы синхронизации
Калишенко Е.Л.
ПОМИ 2014
Попытка № 1
class LockOne implements Lock {
// thread-local index, 0 or 1
private boolean[] flag = new boolean[2];
public void lock() {
int i = ThreadID.get();
int j = 1 - i;
flag[i] = true;
while (flag[j]) {} // wait
}
public void unlock() {
int i = ThreadID.get();
flag[i] = false;
}
}
Попытка № 2
class LockTwo implements Lock {
private volatile int victim;
public void lock() {
int i = ThreadID.get();
victim = i;
// let the other go first
while (victim == i) {} // wait
}
public void unlock() {}
}
Mutex для 2 потоков
class Peterson implements Lock {
// thread-local index, 0 or 1
private volatile boolean[] flag = new boolean[2];
private volatile int victim;
public void lock() {
int i = ThreadID.get();
int j = 1 - i;
flag[i] = true; // I’m interested
victim = i; // you go first
while (flag[j] && victim == i) {}; // wait
}
public void unlock() {
int i = ThreadID.get();
flag[i] = false; //I’m not interested
}
}
Алгоритм булочника
class Bakery implements Lock {
boolean[] flag;
Label[] label;
public Bakery (int n) {
flag = new boolean[n];
label = new Label[n];
for (int i = 0; i < n; i++) {
flag[i] = false; label[i] = 0;
}
}
public void lock() {
int i = ThreadID.get();
flag[i] = true;
label[i] = max(label[0], ...,label[n-1]) + 1;
while ((∃k != i)(flag[k] && (label[k],k) <<
(label[i],i))) {};
}
public void unlock() {
flag[ThreadID.get()] = false;
}
}
POSIX mutex
Тип: pthread_mutex_t
Жизнь:
●
инициализация:инициализация:
pthread_mutex_init или PTHREAD_MUTEX_INITIALIZER
●
запрос на монопольное использование:запрос на монопольное использование:
pthread_mutex_lock или
pthread_mutex_timedlock
●
отказ от монопольного использования:отказ от монопольного использования:
pthread_mutex_unlock
●
тестирование монопольного использования:тестирование монопольного использования:
pthread_mutex_trylock
●
разрушение:разрушение:
pthread_mutex_destroy
mutex && recursive_mutex
Функции:Функции:
● Захват: void lock();
● Попытаться захватить: bool try_lock();
● Освободить: void unlock();
timed_mutex &&
recursive_timed_mutex
Функции:Функции:
● То же, что у mutex && recursive_mutex
➢ Захват: void lock();
➢ Попытаться захватить: bool try_lock();
➢ Освободить: void unlock();
● + Захват с ограничением: timed_lock(...);
shared_mutex
Функции:Функции:
● То же, что у [recursive_]timed_mutex
● Захват: void lock();
● Попытаться захватить: bool try_lock();
● Освободить: void unlock();
● Захват с ограничением: void timed_lock(...);
● + Захват на чтение: void [timed_]lock_shared();
● + Захват на чтение с возможностью
«дозахвата» на запись: void lock_upgrade();
spin_mutex
Функции:Функции:
● То же, что у timed_mutex
● Захват: void lock();
● Попытаться захватить: bool try_lock();
● Освободить: void unlock();
● Захват с ограничением: void timed_lock(...);
Отличие:Отличие:
● Активное ожидание на захвате
CAS-операции
CAS — compare-and-set, compare-and-swap
bool compare_and_set(
● int* <адрес переменной>,
● int <старое значение>,
● int <новое значение>)
✔ Возвращает признак успешности операции
установки значения
✔ Атомарна на уровне процессора (CPU: i486+):
cmpxchg
Преимущества CAS
● Является аппаратным примитивом
● Возможность продолжения захвата
примитива без обязательного перехода в
режим «ожидания»
● Меньше вероятность возникновения
блокировки из-за более мелкой операции
● Более быстрая (правда не в условиях
жёсткой конкуренции)
Пример CAS инкремента
/**
 * Atomically increments by one the current value.
 * @return the updated value
 */
public final int incrementAndGet() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return next;
    }
}
Релизация spin_mutex
Мьютексы
На примере boost:На примере boost:
● mutex
● recursive_mutex
● timed_mutex
● recursive_timed_mutex
● shared_mutex
● spin_mutex
Замки
● lock_guard
● unique_lock
● shared_lock
● upgrade_lock
● upgrade_to_unique_lock
lock_guard
● Захват в конструкторе
● Освобождение в деструкторе
● Используются методы мьютексов
● Захват: void lock();
● Освободить: void unlock();
unique_lock
● То же, что lock_guard
● + Используются методы мьютексов
● Попытаться захватить: bool try_lock();
● Захват с ограничением: void timed_lock(...);
● + Дополнительные функции получения
мьютекса, проверки «захваченности»...
shared_lock
● Предназначени для работы с shared_mutex
● Захват на чтение
● Освобождение в деструкторе
● Используются методы мьютексов
● Захват: void [timed_]lock_shared();
● Освободить: void unlock_shared();
upgrade_lock
● Предназначени для работы с shared_mutex
● Захват на чтение с возможностью
«дозахвата» на запись
● Освобождение в деструкторе
● Используются методы мьютексов
● Захват: void lock_upgrade();
● Освободить: void unlock_upgrade();
upgrade_to_unique_lock
● Предназначени для работы с upgrade_lock
● Захват на запись после захвата на чтение
● Освобождение в деструкторе
● Используются методы мьютексов
● Захват: void unlock_upgrade_and_lock();
● Освободить: void unlock_and_lock_upgrade();
Применение замков
● Мьютекс имеет свой typedef на scoped_lock:
● mutex:
typedef unique_lock<mutex> scoped_lock;
● recursive_mutex:
typedef unique_lock<recursive_mutex> scoped_lock;
● timed_mutex:
typedef unique_lock<timed_mutex> scoped_timed_lock;
typedef scoped_timed_lock scoped_lock;
● Удобнее захватывать:
boost::mutex::scoped_lock l(m);
Futex
Futex - 'Fast Userspace muTexes'
● Применяются для реализации POSIX mutex
● Доступен с ядра 2.5.40
● В реализации используется с CAS — почти
все операции проводятся в пространстве
пользователя
Реализация futex
174 static void
175 futexunlock(Lock *l)
176 {
177 uint32 v;
178
179 v = runtime·xchg(&l->key, MUTEX_UNLOCKED);
180 if(v == MUTEX_UNLOCKED)
181 runtime·throw("unlock of unlocked lock");
182 if(v == MUTEX_SLEEPING)
183 futexwakeup(&l->key, 1);
184 }
Критическая секция
● Разница с мьютексом во многом
терминологическая
● Критическая секция — не объект ядра ОС
● Использование аналогична pthread_mutex_t
➢ InitializeCriticalSection
➢ ::EnterCriticalSection(&m_lock);
➢ ::LeaveCriticalSection(&m_lock);
● Для удобства также как и с мьютексами
используются замки: CScopeLock...
Interlocked-функции
● Тоже работают в пространстве пользователя, не
переводя процесс в режим ожидания, так как
основаны на CAS-операциях
● Примеры:
➢ InterlockedIncrement(&var)
➢ InterlockedExchange
➢ InterlockedCompareExchange
➢ ...
Барьев для N потоков
#define SYNC_MAX_COUNT 10
void SynchronizationPoint() {
static mutex_t sync_lock = PTHREAD_MUTEX_INITIALIZER;
static cond_t sync_cond = PTHREAD_COND_INITIALIZER;
static int sync_count = 0;
/* блокировка доступа к счетчику */
pthread_mutex_lock(&sync_lock);
sync_count++;
/* проверка: следует ли продолжать ожидание */
if (sync_count < SYNC_MAX_COUNT)
pthread_cond_wait(&sync_cond, &sync_lock);
else
/* оповестить о достижении данной точки всеми */
pthread_cond_broadcast(&sync_cond);
/* активизация взаимной блокировки - в противном случае
из процедуры сможет выйти только одна нить! */
pthread_mutex_unlock(&sync_lock);
}
Условные переменные
● Нужны как механизм взаимодействия
потоков, в отличие от мьютексов
● Всегда используется с мьютексом
● Предназначена для уведомления событии
● Атомарно освобождает мьютекс при wait()
● Хорошо подходит для задач типа
«производитель-потребитель»
● Для boost: boost::condition
POSIX condition variable
Тип: pthread_cond_t
Жизнь:
●
инициализация:инициализация:
pthread_cond_init или
PTHREAD_C OND_INITIALIZER
●
ожиданиеожидание
pthread_cond_wait или
pthread_cond_timedwait
●
сигнализация:сигнализация:
pthread_cond_signal или pthread_cond_broadcast
●
разрушение:разрушение:
pthread_cond_destroy
Пример использования
public void prepareData() {
synchronized (monitor) {
System.out.println("Data prepared");
ready = true;
monitor.notifyAll();
}
}
public void sendData() {
synchronized (monitor) {
System.out.println("Waiting for data...");
while (!ready) {
try {
monitor.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Sending data...");
}
}
Оптимальное число потоков
Boost:
boost::thread::hardware_concurrency()boost::thread::hardware_concurrency()
Java:
Runtime.getRuntime().availableProcessors()Runtime.getRuntime().availableProcessors()

Weitere ähnliche Inhalte

Was ist angesagt?

Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...
Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...
Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...Yandex
 
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...Alexey Paznikov
 
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...Alexey Paznikov
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кодаAndrey Karpov
 
SSL/TLS: история уязвимостей
SSL/TLS: история уязвимостейSSL/TLS: история уязвимостей
SSL/TLS: история уязвимостейPositive Hack Days
 
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...Alexey Paznikov
 
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...Alexey Paznikov
 
ПВТ - весна 2015 - Лекция 0. Описание курса
ПВТ - весна 2015 - Лекция 0. Описание курсаПВТ - весна 2015 - Лекция 0. Описание курса
ПВТ - весна 2015 - Лекция 0. Описание курсаAlexey Paznikov
 
Windows Azure and node js
Windows Azure and node jsWindows Azure and node js
Windows Azure and node jsAlex Tumanoff
 
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...Sergey Platonov
 
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...Alexey Paznikov
 
Hunting for a C++ package manager
Hunting for a C++ package managerHunting for a C++ package manager
Hunting for a C++ package managercorehard_by
 
Владимир Горбенко «Использование блоков в Objective-C»
Владимир Горбенко «Использование блоков в Objective-C»Владимир Горбенко «Использование блоков в Objective-C»
Владимир Горбенко «Использование блоков в Objective-C»e-Legion
 
Boost.Algorithm: что, зачем и почему
Boost.Algorithm: что, зачем и почемуBoost.Algorithm: что, зачем и почему
Boost.Algorithm: что, зачем и почемуcorehard_by
 
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...Alexey Paznikov
 
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMДмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMSergey Platonov
 
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...Alexey Paznikov
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияSergey Platonov
 

Was ist angesagt? (20)

Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...
Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...
Филипп Торчинский «Анализ производительности и отладка приложений с помощью D...
 
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
 
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода
 
SSL/TLS: история уязвимостей
SSL/TLS: история уязвимостейSSL/TLS: история уязвимостей
SSL/TLS: история уязвимостей
 
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
 
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
 
ПВТ - весна 2015 - Лекция 0. Описание курса
ПВТ - весна 2015 - Лекция 0. Описание курсаПВТ - весна 2015 - Лекция 0. Описание курса
ПВТ - весна 2015 - Лекция 0. Описание курса
 
Windows Azure and node js
Windows Azure and node jsWindows Azure and node js
Windows Azure and node js
 
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
 
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
 
Hunting for a C++ package manager
Hunting for a C++ package managerHunting for a C++ package manager
Hunting for a C++ package manager
 
Parallel STL
Parallel STLParallel STL
Parallel STL
 
Владимир Горбенко «Использование блоков в Objective-C»
Владимир Горбенко «Использование блоков в Objective-C»Владимир Горбенко «Использование блоков в Objective-C»
Владимир Горбенко «Использование блоков в Objective-C»
 
Boost.Algorithm: что, зачем и почему
Boost.Algorithm: что, зачем и почемуBoost.Algorithm: что, зачем и почему
Boost.Algorithm: что, зачем и почему
 
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
 
Bytecode
BytecodeBytecode
Bytecode
 
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVMДмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
 
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
 
Григорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизацияГригорий Демченко, Асинхронность и неблокирующая синхронизация
Григорий Демченко, Асинхронность и неблокирующая синхронизация
 

Ähnlich wie 20140310 parallel programming_kalishenko_lecture03-04

Введение в разработку многопоточных приложений
Введение в разработку многопоточных приложенийВведение в разработку многопоточных приложений
Введение в разработку многопоточных приложенийCUSTIS
 
Programming Java - Lection 06 - Multithreading - Lavrentyev Fedor
Programming Java - Lection 06 - Multithreading - Lavrentyev FedorProgramming Java - Lection 06 - Multithreading - Lavrentyev Fedor
Programming Java - Lection 06 - Multithreading - Lavrentyev FedorFedor Lavrentyev
 
JPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerJPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerAnton Arhipov
 
Юнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, GoogleЮнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, Googleyaevents
 
ПВТ - осень 2014 - Лекция 3 - Стандарт POSIX Threads
ПВТ - осень 2014 - Лекция 3 - Стандарт POSIX ThreadsПВТ - осень 2014 - Лекция 3 - Стандарт POSIX Threads
ПВТ - осень 2014 - Лекция 3 - Стандарт POSIX ThreadsAlexey Paznikov
 
Асинхронность и сопрограммы
Асинхронность и сопрограммыАсинхронность и сопрограммы
Асинхронность и сопрограммыPlatonov Sergey
 
[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux
[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux
[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/LinuxDefconRussia
 
Тонкости асинхронного программирования
Тонкости асинхронного программированияТонкости асинхронного программирования
Тонкости асинхронного программированияSergey Teplyakov
 
SECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/Linux
SECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/LinuxSECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/Linux
SECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/LinuxSECON
 
C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.Igor Shkulipa
 
Поговорим о JavaScript, основы и современные тенденции развития языка
Поговорим о JavaScript, основы и современные тенденции развития языкаПоговорим о JavaScript, основы и современные тенденции развития языка
Поговорим о JavaScript, основы и современные тенденции развития языкаAlexander Kucherenko
 

Ähnlich wie 20140310 parallel programming_kalishenko_lecture03-04 (14)

Введение в разработку многопоточных приложений
Введение в разработку многопоточных приложенийВведение в разработку многопоточных приложений
Введение в разработку многопоточных приложений
 
Programming Java - Lection 06 - Multithreading - Lavrentyev Fedor
Programming Java - Lection 06 - Multithreading - Lavrentyev FedorProgramming Java - Lection 06 - Multithreading - Lavrentyev Fedor
Programming Java - Lection 06 - Multithreading - Lavrentyev Fedor
 
Thread
ThreadThread
Thread
 
JPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerJPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profiler
 
Юнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, GoogleЮнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, Google
 
ПВТ - осень 2014 - Лекция 3 - Стандарт POSIX Threads
ПВТ - осень 2014 - Лекция 3 - Стандарт POSIX ThreadsПВТ - осень 2014 - Лекция 3 - Стандарт POSIX Threads
ПВТ - осень 2014 - Лекция 3 - Стандарт POSIX Threads
 
Асинхронность и сопрограммы
Асинхронность и сопрограммыАсинхронность и сопрограммы
Асинхронность и сопрограммы
 
[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux
[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux
[Defcon Russia #29] Михаил Клементьев - Обнаружение руткитов в GNU/Linux
 
Lec 14
Lec 14Lec 14
Lec 14
 
Тонкости асинхронного программирования
Тонкости асинхронного программированияТонкости асинхронного программирования
Тонкости асинхронного программирования
 
Linux Kernel Processes
Linux Kernel ProcessesLinux Kernel Processes
Linux Kernel Processes
 
SECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/Linux
SECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/LinuxSECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/Linux
SECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/Linux
 
C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.
 
Поговорим о JavaScript, основы и современные тенденции развития языка
Поговорим о JavaScript, основы и современные тенденции развития языкаПоговорим о JavaScript, основы и современные тенденции развития языка
Поговорим о JavaScript, основы и современные тенденции развития языка
 

Mehr von Computer Science Club

20140531 serebryany lecture01_fantastic_cpp_bugs
20140531 serebryany lecture01_fantastic_cpp_bugs20140531 serebryany lecture01_fantastic_cpp_bugs
20140531 serebryany lecture01_fantastic_cpp_bugsComputer Science Club
 
20140531 serebryany lecture02_find_scary_cpp_bugs
20140531 serebryany lecture02_find_scary_cpp_bugs20140531 serebryany lecture02_find_scary_cpp_bugs
20140531 serebryany lecture02_find_scary_cpp_bugsComputer Science Club
 
20140531 serebryany lecture01_fantastic_cpp_bugs
20140531 serebryany lecture01_fantastic_cpp_bugs20140531 serebryany lecture01_fantastic_cpp_bugs
20140531 serebryany lecture01_fantastic_cpp_bugsComputer Science Club
 
20140511 parallel programming_kalishenko_lecture12
20140511 parallel programming_kalishenko_lecture1220140511 parallel programming_kalishenko_lecture12
20140511 parallel programming_kalishenko_lecture12Computer Science Club
 
20140427 parallel programming_zlobin_lecture11
20140427 parallel programming_zlobin_lecture1120140427 parallel programming_zlobin_lecture11
20140427 parallel programming_zlobin_lecture11Computer Science Club
 
20140420 parallel programming_kalishenko_lecture10
20140420 parallel programming_kalishenko_lecture1020140420 parallel programming_kalishenko_lecture10
20140420 parallel programming_kalishenko_lecture10Computer Science Club
 
20140413 parallel programming_kalishenko_lecture09
20140413 parallel programming_kalishenko_lecture0920140413 parallel programming_kalishenko_lecture09
20140413 parallel programming_kalishenko_lecture09Computer Science Club
 
20140329 graph drawing_dainiak_lecture02
20140329 graph drawing_dainiak_lecture0220140329 graph drawing_dainiak_lecture02
20140329 graph drawing_dainiak_lecture02Computer Science Club
 
20140329 graph drawing_dainiak_lecture01
20140329 graph drawing_dainiak_lecture0120140329 graph drawing_dainiak_lecture01
20140329 graph drawing_dainiak_lecture01Computer Science Club
 
20140216 parallel programming_kalishenko_lecture01
20140216 parallel programming_kalishenko_lecture0120140216 parallel programming_kalishenko_lecture01
20140216 parallel programming_kalishenko_lecture01Computer Science Club
 

Mehr von Computer Science Club (20)

20141223 kuznetsov distributed
20141223 kuznetsov distributed20141223 kuznetsov distributed
20141223 kuznetsov distributed
 
Computer Vision
Computer VisionComputer Vision
Computer Vision
 
20140531 serebryany lecture01_fantastic_cpp_bugs
20140531 serebryany lecture01_fantastic_cpp_bugs20140531 serebryany lecture01_fantastic_cpp_bugs
20140531 serebryany lecture01_fantastic_cpp_bugs
 
20140531 serebryany lecture02_find_scary_cpp_bugs
20140531 serebryany lecture02_find_scary_cpp_bugs20140531 serebryany lecture02_find_scary_cpp_bugs
20140531 serebryany lecture02_find_scary_cpp_bugs
 
20140531 serebryany lecture01_fantastic_cpp_bugs
20140531 serebryany lecture01_fantastic_cpp_bugs20140531 serebryany lecture01_fantastic_cpp_bugs
20140531 serebryany lecture01_fantastic_cpp_bugs
 
20140511 parallel programming_kalishenko_lecture12
20140511 parallel programming_kalishenko_lecture1220140511 parallel programming_kalishenko_lecture12
20140511 parallel programming_kalishenko_lecture12
 
20140427 parallel programming_zlobin_lecture11
20140427 parallel programming_zlobin_lecture1120140427 parallel programming_zlobin_lecture11
20140427 parallel programming_zlobin_lecture11
 
20140420 parallel programming_kalishenko_lecture10
20140420 parallel programming_kalishenko_lecture1020140420 parallel programming_kalishenko_lecture10
20140420 parallel programming_kalishenko_lecture10
 
20140413 parallel programming_kalishenko_lecture09
20140413 parallel programming_kalishenko_lecture0920140413 parallel programming_kalishenko_lecture09
20140413 parallel programming_kalishenko_lecture09
 
20140329 graph drawing_dainiak_lecture02
20140329 graph drawing_dainiak_lecture0220140329 graph drawing_dainiak_lecture02
20140329 graph drawing_dainiak_lecture02
 
20140329 graph drawing_dainiak_lecture01
20140329 graph drawing_dainiak_lecture0120140329 graph drawing_dainiak_lecture01
20140329 graph drawing_dainiak_lecture01
 
20140223-SuffixTrees-lecture01-03
20140223-SuffixTrees-lecture01-0320140223-SuffixTrees-lecture01-03
20140223-SuffixTrees-lecture01-03
 
20140216 parallel programming_kalishenko_lecture01
20140216 parallel programming_kalishenko_lecture0120140216 parallel programming_kalishenko_lecture01
20140216 parallel programming_kalishenko_lecture01
 
20131106 h10 lecture6_matiyasevich
20131106 h10 lecture6_matiyasevich20131106 h10 lecture6_matiyasevich
20131106 h10 lecture6_matiyasevich
 
20131027 h10 lecture5_matiyasevich
20131027 h10 lecture5_matiyasevich20131027 h10 lecture5_matiyasevich
20131027 h10 lecture5_matiyasevich
 
20131027 h10 lecture5_matiyasevich
20131027 h10 lecture5_matiyasevich20131027 h10 lecture5_matiyasevich
20131027 h10 lecture5_matiyasevich
 
20131013 h10 lecture4_matiyasevich
20131013 h10 lecture4_matiyasevich20131013 h10 lecture4_matiyasevich
20131013 h10 lecture4_matiyasevich
 
20131006 h10 lecture3_matiyasevich
20131006 h10 lecture3_matiyasevich20131006 h10 lecture3_matiyasevich
20131006 h10 lecture3_matiyasevich
 
20131006 h10 lecture3_matiyasevich
20131006 h10 lecture3_matiyasevich20131006 h10 lecture3_matiyasevich
20131006 h10 lecture3_matiyasevich
 
20131006 h10 lecture2_matiyasevich
20131006 h10 lecture2_matiyasevich20131006 h10 lecture2_matiyasevich
20131006 h10 lecture2_matiyasevich
 

20140310 parallel programming_kalishenko_lecture03-04

  • 2. Попытка № 1 class LockOne implements Lock { // thread-local index, 0 or 1 private boolean[] flag = new boolean[2]; public void lock() { int i = ThreadID.get(); int j = 1 - i; flag[i] = true; while (flag[j]) {} // wait } public void unlock() { int i = ThreadID.get(); flag[i] = false; } }
  • 3. Попытка № 2 class LockTwo implements Lock { private volatile int victim; public void lock() { int i = ThreadID.get(); victim = i; // let the other go first while (victim == i) {} // wait } public void unlock() {} }
  • 4. Mutex для 2 потоков class Peterson implements Lock { // thread-local index, 0 or 1 private volatile boolean[] flag = new boolean[2]; private volatile int victim; public void lock() { int i = ThreadID.get(); int j = 1 - i; flag[i] = true; // I’m interested victim = i; // you go first while (flag[j] && victim == i) {}; // wait } public void unlock() { int i = ThreadID.get(); flag[i] = false; //I’m not interested } }
  • 5. Алгоритм булочника class Bakery implements Lock { boolean[] flag; Label[] label; public Bakery (int n) { flag = new boolean[n]; label = new Label[n]; for (int i = 0; i < n; i++) { flag[i] = false; label[i] = 0; } } public void lock() { int i = ThreadID.get(); flag[i] = true; label[i] = max(label[0], ...,label[n-1]) + 1; while ((∃k != i)(flag[k] && (label[k],k) << (label[i],i))) {}; } public void unlock() { flag[ThreadID.get()] = false; } }
  • 6. POSIX mutex Тип: pthread_mutex_t Жизнь: ● инициализация:инициализация: pthread_mutex_init или PTHREAD_MUTEX_INITIALIZER ● запрос на монопольное использование:запрос на монопольное использование: pthread_mutex_lock или pthread_mutex_timedlock ● отказ от монопольного использования:отказ от монопольного использования: pthread_mutex_unlock ● тестирование монопольного использования:тестирование монопольного использования: pthread_mutex_trylock ● разрушение:разрушение: pthread_mutex_destroy
  • 7. mutex && recursive_mutex Функции:Функции: ● Захват: void lock(); ● Попытаться захватить: bool try_lock(); ● Освободить: void unlock();
  • 8. timed_mutex && recursive_timed_mutex Функции:Функции: ● То же, что у mutex && recursive_mutex ➢ Захват: void lock(); ➢ Попытаться захватить: bool try_lock(); ➢ Освободить: void unlock(); ● + Захват с ограничением: timed_lock(...);
  • 9. shared_mutex Функции:Функции: ● То же, что у [recursive_]timed_mutex ● Захват: void lock(); ● Попытаться захватить: bool try_lock(); ● Освободить: void unlock(); ● Захват с ограничением: void timed_lock(...); ● + Захват на чтение: void [timed_]lock_shared(); ● + Захват на чтение с возможностью «дозахвата» на запись: void lock_upgrade();
  • 10. spin_mutex Функции:Функции: ● То же, что у timed_mutex ● Захват: void lock(); ● Попытаться захватить: bool try_lock(); ● Освободить: void unlock(); ● Захват с ограничением: void timed_lock(...); Отличие:Отличие: ● Активное ожидание на захвате
  • 11. CAS-операции CAS — compare-and-set, compare-and-swap bool compare_and_set( ● int* <адрес переменной>, ● int <старое значение>, ● int <новое значение>) ✔ Возвращает признак успешности операции установки значения ✔ Атомарна на уровне процессора (CPU: i486+): cmpxchg
  • 12. Преимущества CAS ● Является аппаратным примитивом ● Возможность продолжения захвата примитива без обязательного перехода в режим «ожидания» ● Меньше вероятность возникновения блокировки из-за более мелкой операции ● Более быстрая (правда не в условиях жёсткой конкуренции)
  • 15. Мьютексы На примере boost:На примере boost: ● mutex ● recursive_mutex ● timed_mutex ● recursive_timed_mutex ● shared_mutex ● spin_mutex
  • 16. Замки ● lock_guard ● unique_lock ● shared_lock ● upgrade_lock ● upgrade_to_unique_lock
  • 17. lock_guard ● Захват в конструкторе ● Освобождение в деструкторе ● Используются методы мьютексов ● Захват: void lock(); ● Освободить: void unlock();
  • 18. unique_lock ● То же, что lock_guard ● + Используются методы мьютексов ● Попытаться захватить: bool try_lock(); ● Захват с ограничением: void timed_lock(...); ● + Дополнительные функции получения мьютекса, проверки «захваченности»...
  • 19. shared_lock ● Предназначени для работы с shared_mutex ● Захват на чтение ● Освобождение в деструкторе ● Используются методы мьютексов ● Захват: void [timed_]lock_shared(); ● Освободить: void unlock_shared();
  • 20. upgrade_lock ● Предназначени для работы с shared_mutex ● Захват на чтение с возможностью «дозахвата» на запись ● Освобождение в деструкторе ● Используются методы мьютексов ● Захват: void lock_upgrade(); ● Освободить: void unlock_upgrade();
  • 21. upgrade_to_unique_lock ● Предназначени для работы с upgrade_lock ● Захват на запись после захвата на чтение ● Освобождение в деструкторе ● Используются методы мьютексов ● Захват: void unlock_upgrade_and_lock(); ● Освободить: void unlock_and_lock_upgrade();
  • 22. Применение замков ● Мьютекс имеет свой typedef на scoped_lock: ● mutex: typedef unique_lock<mutex> scoped_lock; ● recursive_mutex: typedef unique_lock<recursive_mutex> scoped_lock; ● timed_mutex: typedef unique_lock<timed_mutex> scoped_timed_lock; typedef scoped_timed_lock scoped_lock; ● Удобнее захватывать: boost::mutex::scoped_lock l(m);
  • 23. Futex Futex - 'Fast Userspace muTexes' ● Применяются для реализации POSIX mutex ● Доступен с ядра 2.5.40 ● В реализации используется с CAS — почти все операции проводятся в пространстве пользователя
  • 24. Реализация futex 174 static void 175 futexunlock(Lock *l) 176 { 177 uint32 v; 178 179 v = runtime·xchg(&l->key, MUTEX_UNLOCKED); 180 if(v == MUTEX_UNLOCKED) 181 runtime·throw("unlock of unlocked lock"); 182 if(v == MUTEX_SLEEPING) 183 futexwakeup(&l->key, 1); 184 }
  • 25. Критическая секция ● Разница с мьютексом во многом терминологическая ● Критическая секция — не объект ядра ОС ● Использование аналогична pthread_mutex_t ➢ InitializeCriticalSection ➢ ::EnterCriticalSection(&m_lock); ➢ ::LeaveCriticalSection(&m_lock); ● Для удобства также как и с мьютексами используются замки: CScopeLock...
  • 26. Interlocked-функции ● Тоже работают в пространстве пользователя, не переводя процесс в режим ожидания, так как основаны на CAS-операциях ● Примеры: ➢ InterlockedIncrement(&var) ➢ InterlockedExchange ➢ InterlockedCompareExchange ➢ ...
  • 27. Барьев для N потоков #define SYNC_MAX_COUNT 10 void SynchronizationPoint() { static mutex_t sync_lock = PTHREAD_MUTEX_INITIALIZER; static cond_t sync_cond = PTHREAD_COND_INITIALIZER; static int sync_count = 0; /* блокировка доступа к счетчику */ pthread_mutex_lock(&sync_lock); sync_count++; /* проверка: следует ли продолжать ожидание */ if (sync_count < SYNC_MAX_COUNT) pthread_cond_wait(&sync_cond, &sync_lock); else /* оповестить о достижении данной точки всеми */ pthread_cond_broadcast(&sync_cond); /* активизация взаимной блокировки - в противном случае из процедуры сможет выйти только одна нить! */ pthread_mutex_unlock(&sync_lock); }
  • 28. Условные переменные ● Нужны как механизм взаимодействия потоков, в отличие от мьютексов ● Всегда используется с мьютексом ● Предназначена для уведомления событии ● Атомарно освобождает мьютекс при wait() ● Хорошо подходит для задач типа «производитель-потребитель» ● Для boost: boost::condition
  • 29. POSIX condition variable Тип: pthread_cond_t Жизнь: ● инициализация:инициализация: pthread_cond_init или PTHREAD_C OND_INITIALIZER ● ожиданиеожидание pthread_cond_wait или pthread_cond_timedwait ● сигнализация:сигнализация: pthread_cond_signal или pthread_cond_broadcast ● разрушение:разрушение: pthread_cond_destroy
  • 30. Пример использования public void prepareData() { synchronized (monitor) { System.out.println("Data prepared"); ready = true; monitor.notifyAll(); } } public void sendData() { synchronized (monitor) { System.out.println("Waiting for data..."); while (!ready) { try { monitor.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("Sending data..."); } }