SlideShare uma empresa Scribd logo
1 de 43
Асинхронность и
неблокирующая
синхронизация
Григорий Демченко, 2016
План
▌Простой сервер
▌Сопрограммы
▌Планировщики
▌Синхронизация
▌Заключение
Простой сервер
Асинхронность и неблокирующая синхронизация
4
Синхронный многопоточный сервер
5
void multitheadedServer() {
Acceptor acceptor{80}; // слушаем 80 порт
while (true) {
auto socket = acceptor.accept(); // 1-й блокирующий вызов
thread([socket] {
auto request = socket.read(); // 2-й блокирующий вызов
auto response = handleRequest(request);
socket.write(response); // 3-й блокирующий вызов
}).detach();
}
}
Асинхронный сервер
6
void asynchronousServer() {
Acceptor acceptor{80};
acceptor.onAccept([] (auto socket) { // 1-й асинхронный вызов
socket.onRead([socket](auto request) { // 2-й асинхронный вызов
auto response = handleRequest(request);
socket.onWrite(response, []() { // 3-й асинхронный вызов
// завершение
});
});
// продолжаем принимать соединения...
});
}
Реальный асинхронный сервер
7
void realAsynchronousServer() {
Acceptor acceptor{80};
Handler accepting = [&acceptor, &accepting] {
struct Connection {
explicit Connection(Socket sock) : socket(std::move(sock)) {}
void onConnect() {
if (error)
return onError(error);
socket.onRead([this](const Request& request, const Error& error) {
if (error)
return onError(error);
response = handlerRequest(request);
socket.onWrite(response, [this](const Error& error) {
if (error)
return onError(error);
onDone();
});
});
}
private:
void onError(const Error& error) {
delete this;
}
void onDone() {
delete this;
}
Response response;
Socket socket;
};
acceptor.onAccept([&accepting](Socket socket, const Error& error) {
if (!error) {
(new Connection{socket})->onConnect();
accepting();
}
});
};
}
▌ Сравните:
void asynchronousServer() {
Acceptor acceptor{80};
acceptor.onAccept([] (socket) {
socket.onRead([socket](request) {
response = handleRequest(request);
socket.onWrite(response, []() {
// завершение
});
});
// продолжаем принимать соединения
});
}
Асинхронный сервер: обсуждение
8
▌ Плюсы:
› Производительность
› Автоматическая параллелизация исполнения
▌ Минусы:
› Сложность:
1. Нелинейный рост сложности и проблем
2. Явная передача контекста исполнения
3. Обработка ошибок
4. Время жизни объектов
5. Отладка
Что бы хотелось?
9
▌ Использовать эффективность асинхронного подхода
▌ Использовать простоту синхронного подхода
│ Решение: использовать
│ сопрограммы
10
Сопрограммы
Асинхронность и неблокирующая синхронизация
Сопрограммы
▌ Подпрограмма: полное выполнение действий
▌ Сопрограмма: возможно частичное выполнение действий
Т.е. сопрограммы обобщают подпрограммы
Примеры сопрограмм:
▌ Генераторы на языке Python.
▌ Async/await C++ proposal.
Метод сохранения контекста исполнения:
▌ Stackful сопрограммы.
12
Реализация сопрограмм
13
Проблема
▌ Сопрограммы всё еще не являются частью языка
▌ Необходимо применять низкоуровневые примитивы.
Решение: boost.context:
▌ Эффективное решение: использование ассемблера
▌ Десктопные платформы: Windows, Linux, MacOSX
▌ Мобильные платформы: Windows Phone, Android, IOS
▌ Процессоры: x86, x86_64, ARM, Spark, Spark64, PPC, PPC64, MIPS
▌ Компиляторы: GCC, Clang, Visual Studio
boost.context
14
▌ make_fcontext: создает контекст
▌ jump_fcontext: переключает контекст
Использование:
▌ 1. Аллокация памяти под стек
▌ 2. Создание контекста:
coroCtx = make_fcontext(stackPtr, stackSize, coroCb)
▌ 3. Запуск или продолжение исполнения:
jump_fcontext(callerCtx, coroCtx, opaquePtr)
▌ 4. Возвращение или заморозка исполнения:
jump_fcontext(coroCtx, callerCtx, opaquePtr)
Сопрограммы в действии
15
void coroFun() {
log << "2";
yield();
log << "4";
}
log << "1";
Coro c{coroFun};
log << "3";
c.resume();
log << "5";
Вывод:
▌ 12345
Использование сопрограммы
16
Преобразовать асинхронный вызов:
async(completionCallback);
В синхронный:
synca(); // async -> synca
Используя следующий подход:
void synca() {
auto& coro = currentCoro();
async([&coro] {
coro.resume();
});
yield();
}
Sequence Diagram
17
Проблема: состояние гонки
18
Возможные решения
19
▌ std::mutex
▌ boost::asio::strand
▌ defer
Использование defer
20
▌ defer откладывает асинхронный вызов:
using Handler = std::function<void()>;
void defer(Handler handler);
Решение: defer
21
Использование: defer
22
void synca() {
auto& coro = currentCoro();
async([&coro] {
coro.resume();
});
yield();
}
void synca() {
auto& coro = currentCoro();
defer([&coro] {
async([&coro] {
coro.resume();
});
});
}
Абстрагирование от сопрограмм
23
void synca() {
auto& coro = currentCoro();
defer([&coro] {
async([&coro] {
coro.resume();
});
});
}
void synca() {
deferProceed([](Handler proceed) {
async(proceed);
});
}
Synca сервер
24
void syncaServer() {
Acceptor acceptor{80}; // слушаем 80 порт
while (true) {
auto socket = acceptor.accept(); // 1-й неблокирующий вызов
go([socket] { // стартуем новую сопрограмму
auto request = socket.read(); // 2-й неблокирующий вызов
auto response = handleRequest(request);
socket.write(response); // 3-й неблокирующий вызов
});
}
}
Планировщики
Асинхронность и неблокирующая синхронизация
Планировщик
▌ Интерфейс планировщика:
struct IScheduler {
virtual void schedule(Handler) = 0;
};
Плашировщик запускает обработчики.
Пул потоков
27
struct ThreadPool : IScheduler {
explicit ThreadPool(size_t threads);
void schedule(Handler handler) {
service.post(std::move(handler));
}
private:
boost::asio::io_service service;
};
Сопрограммы и планировщик
28
struct Journey {
void defer(Handler handler) {
deferHandler = std::move(handler);
yield();
}
void proceed() {
scheduler->schedule([this] {
coro.resume();
deferHandler();
});
}
private:
IScheduler* scheduler;
Coro coro;
Handler deferHandler;
};
Телепортация
29
▌ Давайте перепрыгнем на другой планировщик:
go([&] {
log << "Inside 1st thread pool";
teleport(tp2);
log << “Inside 2nd thread pool";
}, tp1);
▌ Реализация:
void Journey::teleport(IScheduler& s) {
scheduler = &s;
defer([this] {
proceed();
});
}
Телепортация: Sequence Diagram
30
Порталы
31
▌ Портал – это RAII телепортация:
struct Portal {
Portal(IScheduler& destination)
: source{currentScheduler()} {
teleport(destination);
}
~Portal() {
teleport(source);
}
private:
IScheduler& source;
};
Использование порталов
32
struct Network {
void handleNetworkEvents() {
// действия внутри сетевого пула потоков
}
};
ThreadPool commonPool{4};
ThreadPool networkPool{2};
portal<Network>().attach(networkPool);
go([] {
log << "Inside common pool";
portal<Network>()->handleNetworkEvents();
log << "Inside common pool";
}, commonPool);
│ Портал – абстракция
│ среды исполнения
33
Синхронизация
Асинхронность и неблокирующая синхронизация
Alone
35
struct Alone : IScheduler {
void schedule(Handler handler) {
strand.post(std::move(handler));
}
private:
boost::asio::io_service::strand strand;
};
strand гарантирует, что ни один обработчик не будет запущен
параллельно с другим
│ Alone – это
│ неблокирующая
│ синхронизация
│ без дедлоков
36
Интегральный пример: инициализация
37
struct DiskCache/MemCache {
optional<string> get(const string& key);
void set(const string& key, const string& val);
};
struct Network {
string performRequest(const std::string& key);
};
ThreadPool commonPool{3}; // common operations pool
ThreadPool diskPool{2}; // disk operations pool
ThreadPool netPool{1}; // network operations pool
Alone memAlone{commonPool}; // MemCache access synchronization
portal<DiskCache>().attach(diskPool);
portal<MemCache>().attach(memAlone);
portal<Network>().attach(netPool);
Интегральный пример: получение значения
38
string obtainValue(const string& key) {
auto res = portal<MemCache>()->get(key);
if (res)
return *res;
res = portal<DiskCache>()->get(key);
if (res)
return *res;
auto val = portal<Network>()->performRequest(key);
go([key, val] {
portal<MemCache>()->set(key, val);
portal<DiskCache>()->set(key, val);
});
return val;
}
Свойства портала
39
▌ Работает с исключениями
▌ Абстрагирует контекст исполнения
Выводы
Асинхронность и неблокирующая синхронизация
Теорема
41
Любая асинхронная задача может быть реализована через сопрограммы
▌ 1. Нет кода после вызова:
// код до
async(params..., cb);
// отсутствует код
// код до
synca(params...);
cb();
▌ 2. Есть код после вызова:
// код до
async(..., cb);
// код после
// код до
go { async(..., cb); };
// код после
// код до
go { synca(...); cb(); };
// код после
Выводы
42
▌ Синхронный подход: простота
▌ Асинхронный подход : эффективность
▌ Неблокирующая синхронизация без дедлоков
▌ Работает с исключениями
▌ Прозрачно для использования
▌ Принципиально новые подходы и паттерны
▌ Это прикольно!
https://github.com/gridem/Synca
https://bitbucket.org/gridem/synca
Асинхронность и
неблокирующая синхронизация
habrahabr.ru/users/gridem
gridem.blogspot.com github.com/gridem
bitbucket.org/gridem
Григорий Демченко, Разработчик С++
43

Mais conteúdo relacionado

Mais procurados

Юнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, GoogleЮнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, Google
yaevents
 

Mais procurados (20)

Антон Полухин, Немного о Boost
Антон Полухин, Немного о BoostАнтон Полухин, Немного о Boost
Антон Полухин, Немного о Boost
 
DI в C++ тонкости и нюансы
DI в C++ тонкости и нюансыDI в C++ тонкости и нюансы
DI в C++ тонкости и нюансы
 
Григорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптерГригорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптер
 
C++ exceptions
C++ exceptionsC++ exceptions
C++ exceptions
 
Аскетичная разработка браузера
Аскетичная разработка браузераАскетичная разработка браузера
Аскетичная разработка браузера
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?
 
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
ПВТ - весна 2015 - Лекция 5. Многопоточное программирование в С++. Синхрониза...
 
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияДракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода
 
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
 
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++.   Р...
ПВТ - осень 2014 - Лекция 5 - Многопоточное программирование в языке С++. Р...
 
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
 
Юнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, GoogleЮнит-тестирование и Google Mock. Влад Лосев, Google
Юнит-тестирование и Google Mock. Влад Лосев, Google
 
Фитнес для вашего кода: как держать его в форме
Фитнес для вашего кода: как держать его в формеФитнес для вашего кода: как держать его в форме
Фитнес для вашего кода: как держать его в форме
 
Как за час сделать недельную работу
Как за час сделать недельную работуКак за час сделать недельную работу
Как за час сделать недельную работу
 
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
ПВТ - весна 2015 - Лекция 3. Реентерабельность. Сигналы. Локальные данные пот...
 
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
 
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
 
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...
 
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
 

Destaque

Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Platonov Sergey
 

Destaque (18)

Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptСергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
 
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itEvgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
 
Антон Бикинеев, Reflection in C++Next
Антон Бикинеев,  Reflection in C++NextАнтон Бикинеев,  Reflection in C++Next
Антон Бикинеев, Reflection in C++Next
 
Clang tidy
Clang tidyClang tidy
Clang tidy
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
 
Алексей Кутумов, C++ без исключений, часть 3
Алексей Кутумов,  C++ без исключений, часть 3Алексей Кутумов,  C++ без исключений, часть 3
Алексей Кутумов, C++ без исключений, часть 3
 
C++ Core Guidelines
C++ Core Guidelines C++ Core Guidelines
C++ Core Guidelines
 
Quality assurance of large c++ projects
Quality assurance of large c++ projectsQuality assurance of large c++ projects
Quality assurance of large c++ projects
 
Fuzzing: The New Unit Testing
Fuzzing: The New Unit TestingFuzzing: The New Unit Testing
Fuzzing: The New Unit Testing
 
Василий Сорокин, Простой REST сервер на Qt с рефлексией
Василий Сорокин, Простой REST сервер на Qt с рефлексиейВасилий Сорокин, Простой REST сервер на Qt с рефлексией
Василий Сорокин, Простой REST сервер на Qt с рефлексией
 
Антон Бикинеев, Writing good std::future&lt; C++ >
Антон Бикинеев, Writing good std::future&lt; C++ >Антон Бикинеев, Writing good std::future&lt; C++ >
Антон Бикинеев, Writing good std::future&lt; C++ >
 
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
 
Конкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнерыКонкурентные ассоциативные контейнеры
Конкурентные ассоциативные контейнеры
 
Mixing c++ and python
Mixing c++ and pythonMixing c++ and python
Mixing c++ and python
 
Диаграммы состояний и c++
Диаграммы состояний и c++Диаграммы состояний и c++
Диаграммы состояний и c++
 
Async await in C++
Async await in C++Async await in C++
Async await in C++
 
Gor Nishanov, C++ Coroutines – a negative overhead abstraction
Gor Nishanov,  C++ Coroutines – a negative overhead abstractionGor Nishanov,  C++ Coroutines – a negative overhead abstraction
Gor Nishanov, C++ Coroutines – a negative overhead abstraction
 
строим Microkernel architecture на базе паттерна pipes and filters
строим Microkernel architecture на базе паттерна pipes and filtersстроим Microkernel architecture на базе паттерна pipes and filters
строим Microkernel architecture на базе паттерна pipes and filters
 

Semelhante a Григорий Демченко, Асинхронность и неблокирующая синхронизация

2012 03 14_parallel_programming_lecture05
2012 03 14_parallel_programming_lecture052012 03 14_parallel_programming_lecture05
2012 03 14_parallel_programming_lecture05
Computer Science Club
 
Apache Storm: от простого приложения до подробностей реализации
Apache Storm: от простого приложения до подробностей реализацииApache Storm: от простого приложения до подробностей реализации
Apache Storm: от простого приложения до подробностей реализации
CEE-SEC(R)
 

Semelhante a Григорий Демченко, Асинхронность и неблокирующая синхронизация (20)

Asynchrony and coroutines
Asynchrony and coroutinesAsynchrony and coroutines
Asynchrony and coroutines
 
Асинхронность и сопрограммы
Асинхронность и сопрограммыАсинхронность и сопрограммы
Асинхронность и сопрограммы
 
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
 
Многопоточность в браузере. Модель акторов — Константин Крамлих
Многопоточность в браузере. Модель акторов — Константин КрамлихМногопоточность в браузере. Модель акторов — Константин Крамлих
Многопоточность в браузере. Модель акторов — Константин Крамлих
 
Tarantool Modules, Tarantool Meetup 2016-08-25
Tarantool Modules, Tarantool Meetup 2016-08-25Tarantool Modules, Tarantool Meetup 2016-08-25
Tarantool Modules, Tarantool Meetup 2016-08-25
 
2012 03 14_parallel_programming_lecture05
2012 03 14_parallel_programming_lecture052012 03 14_parallel_programming_lecture05
2012 03 14_parallel_programming_lecture05
 
Ловля сетями. Инструменты отладки сетевых запросов приложений / Дмитрий Рыбак...
Ловля сетями. Инструменты отладки сетевых запросов приложений / Дмитрий Рыбак...Ловля сетями. Инструменты отладки сетевых запросов приложений / Дмитрий Рыбак...
Ловля сетями. Инструменты отладки сетевых запросов приложений / Дмитрий Рыбак...
 
OpenStack - Python Project with 12 Million Lines of code (RUS, Moscow Python ...
OpenStack - Python Project with 12 Million Lines of code (RUS, Moscow Python ...OpenStack - Python Project with 12 Million Lines of code (RUS, Moscow Python ...
OpenStack - Python Project with 12 Million Lines of code (RUS, Moscow Python ...
 
JavaDay'14
JavaDay'14JavaDay'14
JavaDay'14
 
Multithreading in java past and actual
Multithreading in java past and actualMultithreading in java past and actual
Multithreading in java past and actual
 
Миграция данных из Oracle в Postgres
Миграция данных из Oracle в PostgresМиграция данных из Oracle в Postgres
Миграция данных из Oracle в Postgres
 
#PostgreSQLRussia 2015.09.15 - Максим Трегубов, CUSTIS - Миграция из Oracle в...
#PostgreSQLRussia 2015.09.15 - Максим Трегубов, CUSTIS - Миграция из Oracle в...#PostgreSQLRussia 2015.09.15 - Максим Трегубов, CUSTIS - Миграция из Oracle в...
#PostgreSQLRussia 2015.09.15 - Максим Трегубов, CUSTIS - Миграция из Oracle в...
 
Дмитрий Жестилевский — Yet another threading framework: асинхронная разработк...
Дмитрий Жестилевский — Yet another threading framework: асинхронная разработк...Дмитрий Жестилевский — Yet another threading framework: асинхронная разработк...
Дмитрий Жестилевский — Yet another threading framework: асинхронная разработк...
 
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
 
Григорий Демченко — Асинхронное программирование и сопрограммы
Григорий Демченко — Асинхронное программирование и сопрограммыГригорий Демченко — Асинхронное программирование и сопрограммы
Григорий Демченко — Асинхронное программирование и сопрограммы
 
Превышаем скоростные лимиты с Angular 2 / Алексей Охрименко (IPONWEB)
Превышаем скоростные лимиты с Angular 2 / Алексей Охрименко (IPONWEB)Превышаем скоростные лимиты с Angular 2 / Алексей Охрименко (IPONWEB)
Превышаем скоростные лимиты с Angular 2 / Алексей Охрименко (IPONWEB)
 
Превышаем скоростные лимиты с Angular 2
Превышаем скоростные лимиты с Angular 2Превышаем скоростные лимиты с Angular 2
Превышаем скоростные лимиты с Angular 2
 
Node.js введение в технологию, КПИ #ITmeetingKPI
Node.js введение в технологию, КПИ  #ITmeetingKPINode.js введение в технологию, КПИ  #ITmeetingKPI
Node.js введение в технологию, КПИ #ITmeetingKPI
 
Apache Storm: от простого приложения до подробностей реализации
Apache Storm: от простого приложения до подробностей реализацииApache Storm: от простого приложения до подробностей реализации
Apache Storm: от простого приложения до подробностей реализации
 
Леонид Васильев "Python в инфраструктуре поиска"
Леонид Васильев "Python в инфраструктуре поиска"Леонид Васильев "Python в инфраструктуре поиска"
Леонид Васильев "Python в инфраструктуре поиска"
 

Mais de Sergey Platonov

Mais de Sergey Platonov (20)

Лев Казаркин, Удивительные приключения регистров SSE или в поисках одного бага
Лев Казаркин, Удивительные приключения регистров SSE или в поисках одного багаЛев Казаркин, Удивительные приключения регистров SSE или в поисках одного бага
Лев Казаркин, Удивительные приключения регистров SSE или в поисках одного бага
 
Павел Филонов, Разделяй и управляй вместе с Conan.io
Павел Филонов, Разделяй и управляй вместе с Conan.ioПавел Филонов, Разделяй и управляй вместе с Conan.io
Павел Филонов, Разделяй и управляй вместе с Conan.io
 
Антон Полухин. C++17
Антон Полухин. C++17Антон Полухин. C++17
Антон Полухин. C++17
 
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на QtДенис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
Денис Кандров, Пушкова Евгения, QSpec: тестирование графических приложений на Qt
 
Алексей Кутумов, Coroutines everywhere
Алексей Кутумов, Coroutines everywhereАлексей Кутумов, Coroutines everywhere
Алексей Кутумов, Coroutines everywhere
 
Дмитрий Нестерук, Паттерны проектирования в XXI веке
Дмитрий Нестерук, Паттерны проектирования в XXI векеДмитрий Нестерук, Паттерны проектирования в XXI веке
Дмитрий Нестерук, Паттерны проектирования в XXI веке
 
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
 
Павел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладкаПавел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладка
 
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковНикита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
 
Dori Exterman, Considerations for choosing the parallel computing strategy th...
Dori Exterman, Considerations for choosing the parallel computing strategy th...Dori Exterman, Considerations for choosing the parallel computing strategy th...
Dori Exterman, Considerations for choosing the parallel computing strategy th...
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++
 
Антон Нонко, Классические строки в C++
Антон Нонко, Классические строки в C++Антон Нонко, Классические строки в C++
Антон Нонко, Классические строки в C++
 
Михаил Матросов, Повседневный С++: boost и STL
Михаил Матросов, Повседневный С++: boost и STLМихаил Матросов, Повседневный С++: boost и STL
Михаил Матросов, Повседневный С++: boost и STL
 
Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++
 
Алексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуляАлексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуля
 
Kirk Shoop, Reactive programming in C++
Kirk Shoop, Reactive programming in C++Kirk Shoop, Reactive programming in C++
Kirk Shoop, Reactive programming in C++
 
Дмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репортДмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репорт
 
Илья Шишков, Принципы создания тестируемого кода
Илья Шишков, Принципы создания тестируемого кодаИлья Шишков, Принципы создания тестируемого кода
Илья Шишков, Принципы создания тестируемого кода
 
Антон Наумович, Система автоматической крэш-аналитики своими средствами
Антон Наумович, Система автоматической крэш-аналитики своими средствамиАнтон Наумович, Система автоматической крэш-аналитики своими средствами
Антон Наумович, Система автоматической крэш-аналитики своими средствами
 
Андрей Карпов, Приватные байки от разработчиков анализатора кода
Андрей Карпов, Приватные байки от разработчиков анализатора кодаАндрей Карпов, Приватные байки от разработчиков анализатора кода
Андрей Карпов, Приватные байки от разработчиков анализатора кода
 

Григорий Демченко, Асинхронность и неблокирующая синхронизация