![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
Migrating fibers between threadsBoost , Chapter 1. Fiber , Chapter 1. Fiber
|
Установите алгоритм планирования | |
Запустите ряд рабочих волокон; каждое рабочее волокно поднимает характер, который передается в качестве параметра клетчатке | |
Клетчатка для каждого нового волокна. | |
Запустите пару ниточек, которые присоединяются к совместной работе. | |
синхронизация с другими потоками: позволить им начать обработку | |
| |
Приостанавливает основное волокно и возобновляет рабочие волокна тем временем. Основное волокно возобновляется (например, возвращается из | |
Перекрывающий замок mtx_count требуется перед присоединением к нити, иначе другие нити будут заблокированы внутри условия_переменные::wait() и никогда не вернутся (deadlock). | |
ждать, пока не закончится нити |
Начало нитей синхронизировано с барьером. Основное волокно каждой нити (включая основную нить) приостанавливается до тех пор, пока все рабочие волокна не будут заполнены. Когда основное волокно возвращается из condition_variable::wait()
, резьба заканчивается: основная резьба соединяет все остальные нити.
void thread( barrier * b) { std::ostringstream buffer; buffer << "thread started " << std::this_thread::get_id() << std::endl; std::cout << buffer.str() << std::flush; boost::fibers::use_scheduling_algorithm< boost::fibers::algo::shared_work >();b->wait();
lock_t lk( mtx_count); cnd_count.wait( lk, [](){ return 0 == fiber_count; } );
BOOST_ASSERT( 0 == fiber_count); }
Установите алгоритм планирования | |
синхронизация с другими потоками: позволить им начать обработку | |
Приостанавливает основное волокно и возобновляет рабочие волокна тем временем. Основное волокно возобновляется (например, возвращается из |
Каждое рабочее волокно выполняет функцию whatevah()
с характером me
в качестве параметра. Клетчатка уступает в петле и печатает сообщение, если оно было перенесено на другую нить.
void whatevah( char me) { try { std::thread::id my_thread = std::this_thread::get_id();{ std::ostringstream buffer; buffer << "fiber " << me << " started on thread " << my_thread << '\n'; std::cout << buffer.str() << std::flush; } for ( unsigned i = 0; i < 10; ++i) {
boost::this_fiber::yield();
std::thread::id new_thread = std::this_thread::get_id();
if ( new_thread != my_thread) {
my_thread = new_thread; std::ostringstream buffer; buffer << "fiber " << me << " switched to thread " << my_thread << '\n'; std::cout << buffer.str() << std::flush; } } } catch ( ... ) { } lock_t lk( mtx_count); if ( 0 == --fiber_count) {
lk.unlock(); cnd_count.notify_all();
} }
получить идентификационный номер исходного потока | |
10 раз | |
выход к другим волокнам | |
получить идентификатор текущего потока | |
тест, если волокна были перенесены в другую нить | |
Клетчатка для каждого завершенного волокна. | |
Уведомить все волокна ждут на |
График волокна shared_ready_queue
похож на round_robin
, за исключением того, что он разделяет общую готовую очередь среди всех участвующих потоков. Нить участвует в этом бассейне, выполняя use_scheduling_algorithm()
перед любым другим Boost.Fiber операция.
Важным моментом в готовой очереди является то, что она’ классная статичная, общая для всех случаев Share_ready_queue. Таким образом, волокна, завещанные через algorithm::awakened()
(волокны, которые готовы возобновиться), доступны для всех потоков. Требуется резервировать отдельную очередь для резьбы’ основных волоконно-диспетчерских волокон: они могут не быть разделены между нити! Когда мы и #8217; прошли любой из этих волокон, нажмите его там, а не в общей очереди: это были бы плохие новости для нити B, чтобы получить и попытаться выполнить нити A’ основное волокно.
[awakened_ws]
Когда algorithm::pick_next()
вызывается внутри одной нити, волокно выводится из rqueue_ и будет возобновлено в этой нити.
[pick_next_ws]
Исходный код выше содержится в work_sharing.cpp.
[2] “main” волокно на каждой нити, то есть волокно, на котором резьба запущена, не может мигрировать в любую другую нить. Также Boost.Fiber косвенно создает клетчатку диспетчера для каждой нити — это также не может мигрировать.
[3] Конечно, было бы проблематично перенести волокно, которое опирается на -местное хранилище.
Статья Migrating fibers between threads раздела Chapter 1. Fiber Chapter 1. Fiber может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: Chapter 1. Fiber ::
реклама |