Энтони Уильямс - Параллельное программирование на С++ в действии. Практика разработки многопоточных программ

Здесь есть возможность читать онлайн «Энтони Уильямс - Параллельное программирование на С++ в действии. Практика разработки многопоточных программ» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Город: Москва, Год выпуска: 2012, ISBN: 2012, Издательство: ДМК Пресс, Жанр: Программирование, на русском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Параллельное программирование на С++ в действии. Практика разработки многопоточных программ: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Параллельное программирование на С++ в действии. Практика разработки многопоточных программ»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

В наши дни компьютеры с несколькими многоядерными процессорами стали нормой. Стандарт С++11 языка С++ предоставляет развитую поддержку многопоточности в приложениях. Поэтому, чтобы сохранять конкурентоспособность, вы должны овладеть принципами и приемами их разработки, а также новыми средствами языка, относящимися к параллелизму.
Книга «Параллельное программирование на С++ в действии» не предполагает предварительных знаний в этой области. Вдумчиво читая ее, вы научитесь писать надежные и элегантные многопоточные программы на С++11. Вы узнаете о том, что такое потоковая модель памяти, и о том, какие средства поддержки многопоточности, в том числе запуска и синхронизации потоков, имеются в стандартной библиотеке. Попутно вы познакомитесь с различными нетривиальными проблемами программирования в условиях параллелизма.

Параллельное программирование на С++ в действии. Практика разработки многопоточных программ — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Параллельное программирование на С++ в действии. Практика разработки многопоточных программ», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Листинг 9.11.Реализация interruptible_wait()для std::condition_variableс таймаутом

class interrupt_flag {

std::atomic flag;

std::condition_variable* thread_cond;

std::mutex set_clear_mutex;

public:

interrupt_flag(): thread_cond(0) {}

void set() {

flag.store(true, std::memory_order_relaxed);

std::lock_guard lk(set_clear_mutex);

if (thread_cond) {

thread_cond->notify_all();

}

}

bool is_set() const {

return flag.load(std::memory_order_relaxed);

}

void set_condition_variable(std::condition_variable& cv) {

std::lock_guard lk(set_clear_mutex);

thread_cond = &cv;

}

void clear_condition_variable() {

std::lock_guard lk(set_clear_mutex);

thread_cond = 0;

}

struct clear_cv_on_destruct {

~clear_cv_on_destruct() {

this_thread_interrupt_flag.clear_condition_variable();

}

};

};

void interruptible_wait(std::condition_variable& cv,

std::unique_lock& lk) {

interruption_point();

this_thread_interrupt_flag.set_condition_variable(cv);

interrupt_flag::clear_cv_on_destruct guard;

interruption_point();

cv.wait_for(lk, std::chrono::milliseconds(1));

interruption_point();

}

Если мы ждем какой-то предикат, то таймаут продолжительностью 1 мс можно полностью скрыть внутри цикла проверки предиката:

template

void interruptible_wait(std::condition_variable& cv,

std::unique_lock& lk,

Predicate pred) {

interruption_point();

this_thread_interrupt_flag.set_condition_variable(cv);

interrupt_flag::clear_cv_on_destruct guard;

while (!this_thread_interrupt_flag.is_set() && !pred()) {

cv.wait_for(lk, std::chrono::milliseconds(1));

}

interruption_point();

}

Правда, предикат при этом проверяется чаще, чем необходимо, но зато эту функцию легко использовать вместо простого вызова wait(). Легко реализовать и другие варианты функций с таймаутом, например: ждать в течение указанного времени или 1 мс в зависимости от того, что меньше.

Ну хорошо, с ожиданием std::condition_variableмы разобрались, а что сказать о std::condition_variable_any? Всё точно так же или можно сделать лучше?

9.2.4. Прерывание ожидания std::condition_variable_any

Класс std::condition_variable_anyотличается от std::condition_variableтем, что работает с любым типом блокировки, а не только с std::unique_lock. Как выясняется, это сильно упрощает дело, так что мы сможем добиться более впечатляющих результатов, чем получилось с std::condition_variable. Раз допустим любой тип блокировки, то можно написать и свой собственный класс, который захватывает (освобождает) как внутренний мьютекс set_clear_mutexв классе interrupt_flag, так и блокировку, переданную при вызове wait(). Соответствующий код приведён в листинге ниже.

Листинг 9.12.Реализация interruptible_wait()для std::condition_variable_any

class interrupt_flag {

std::atomic flag;

std::condition_variable* thread_cond;

std::condition_variable_any* thread_cond_any;

std::mutex set_clear_mutex;

public:

interrupt_flag():

thread_cond(0), thread_cond_any(0) {}

void set() {

flag.store(true, std::memory_order_relaxed);

std::lock_guard lk(set_clear_mutex);

if (thread_cond) {

thread_cond->notify_all();

} else if (thread_cond_any) {

thread_cond_any->notify_all();

}

}

template

void wait(std::condition_variable_any& cv, Lockable& lk) {

struct custom_lock {

interrupt_flag* self;

Lockable& lk;

custom_lock(interrupt_flag* self_,

std::condition_variable_any& cond,

Lockable& lk_): self(self_), lk(lk_) {

self->set_clear_mutex.lock(); ← (1)

self->thread_cond_any = &cond; ← (2)

}

void unlock() { ← (3)

lk.unlock();

self->set_clear_mutex.unlock();

}

void lock() {

std::lock(self->set_clear_mutex, lk); ← (4)

}

~custom_lock() {

self->thread_cond_any = 0; ← (5)

self->set_clear_mutex.unlock();

}

};

custom_lock cl(this, cv, lk);

interruption_point();

cv.wait(cl);

interruption_point();

}

// остальное, как и раньше

};

template

void interruptible_wait(std::condition_variable_any& cv,

Lockable& lk) {

this_thread_interrupt_flag.wait(cv, lk);

}

Наш класс блокировки должен захватить внутренний мьютекс set_clear_mutexна этапе конструирования (1)и затем записать в переменную thread_cond_anyуказатель на объект std::condition_variable_any, переданный конструктору (2). Ссылка на объект Lockableсохраняется для последующего использования; он должен быть уже заблокирован. Теперь проверять, был ли поток прерван, можно, не опасаясь гонки. Если в этой точке флаг прерывания установлен, то это было сделано до захвата мьютекса set_clear_mutex. Когда условная переменная вызывает нашу функцию unlock()внутри wait(), мы разблокируем объект Lockable и внутренний мьютекс set_clear_mutex (3). Это позволяет потокам, которые пытаются нас прервать, захватить set_clear_mutexи проверить указатель thread_cond_any, когда мы уже находимся в wait(), но не раньше. Это именно то, чего мы хотели (но не смогли) добиться в случае std::condition_variable. После того как wait()завершит ожидание (из-за получения сигнала или вследствие ложного пробуждения), она вызовет нашу функцию lock(), которая снова захватит внутренний мьютекс set_clear_mutexи заблокирует объект Lockable (4). Теперь можно еще раз проверить, не было ли прерываний, пока мы находились в wait(), и только потом обнулить указатель thread_cond_anyв деструкторе custom_lock (5), где также освобождается set_clear_mutex.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Параллельное программирование на С++ в действии. Практика разработки многопоточных программ»

Представляем Вашему вниманию похожие книги на «Параллельное программирование на С++ в действии. Практика разработки многопоточных программ» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Отзывы о книге «Параллельное программирование на С++ в действии. Практика разработки многопоточных программ»

Обсуждение, отзывы о книге «Параллельное программирование на С++ в действии. Практика разработки многопоточных программ» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x