Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Scheduling

Boost , Chapter 1. Fiber , Chapter 1. Fiber

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

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

Boost.Fiber предоставляет диспетчер волокон, но планировщик является точкой настройки. (См. Customization.)

Каждая нить имеет свой планировщик. Различные потоки в процессе могут использовать разные планировщики. По умолчанию Boost.Fiber неявно представляет round_robin в качестве планировщика для каждого потока.

Вам явно разрешено кодировать свой собственный подкласс алгоритм. По большей части вашему подклассу алгоритм не нужно защищаться от поперечных вызовов: менеджер волокон перехватывает и откладывает такие вызовы. Большинство методов алгоритм напрямую вызываются только из потока, волокнами которого он управляет — за исключением случаев, описанных ниже.

Ваш подкласс алгоритм включается в конкретную нить, позвонив use_scheduling_algorithm():

void thread_fn() {
    boost::fibers::use_scheduling_algorithm< my_fiber_scheduler >();
    ...
}

Класс планировщика должен реализовывать интерфейс алгоритм. Boost.Fiber предоставляет один планировщик: round_robin.

Class algorithm

алгоритм является абстрактным базовым классом, определяющим интерфейс, который должен реализовать планировщик волокон.

#include <boost/fiber/algo/algorithm.hpp>
namespace boost {
namespace fibers {
namespace algo {
struct algorithm {
    virtual ~algorithm();
    virtual void awakened( context *) noexcept = 0;
    virtual context * pick_next() noexcept = 0;
    virtual bool has_ready_fibers() const noexcept = 0;
    virtual void suspend_until( std::chrono::steady_clock::time_point const&) noexcept = 0;
    virtual void notify() noexcept = 0;
};
}}}

Member function awakened()

virtual void awakened( context * f) noexcept = 0;

Effects:

Информирует планировщик, что волокно f готово к запуску. Волокно f может быть запущено недавно, или оно может быть заблокировано, но только что было пробуждено, или оно может называться this_fiber::yield().

Note:

Этот метод советует планировщику добавить волокно f в свою коллекцию волокон, готовых к работе. Типичная реализация планировщика помещает f в очередь.

See also:

round_robin

Member function pick_next()

virtual context * pick_next() noexcept = 0;

Returns:

волокно, которое должно быть возобновлено следующим образом, или nullptr, если нет готового волокна.

Note:

Именно здесь планировщик фактически определяет волокно, которое будет работать дальше. Типичная реализация планировщика выбирает главу готовой очереди.

See also:

round_robin

Member function has_ready_fibers()

virtual bool has_ready_fibers() const noexcept = 0;

Returns:

true, если планировщик имеет готовые к запуску волокна.

Member function suspend_until()

virtual void suspend_until( std::chrono::steady_clock::time_point const& abs_time) noexcept = 0;

Effects:

Информирует планировщик, что ни одно волокно не будет готово до точки времени abs_time.

Note:

Этот метод позволяет пользовательскому планировщику передавать контроль в содержащую среду любым способом. Диспетчер волокон утверждает, что suspend_until() не должен возвращаться до тех пор, пока abs_time — или алгоритм::notify() не будет называться — в зависимости от того, что наступит раньше. Взаимодействие с notify()::sleep_until(abs_time) будет слишком упрощенным.round_robin::suspend_until() использует std:: для координации с round_robin::notify().

Note:

Учитывая, что notify() может быть вызван из другого потока, ваша реализация suspend_until() — как и остальная часть вашей реализации algorithm — должна защищать любые данные, которыми она делится с вашей реализацией notify().

Member function notify()

virtual void notify() noexcept = 0;

Effects:

Просит планировщика вернуться с ожидающего вызова на алгоритм::suspend_until().

Note:

Один из методов алгоритм, уведомить() можно вызвать из другого потока. Ваша реализация уведомляет () должна защищать любые данные, которыми она делится с остальной частью вашей реализации алгоритм.

Class round_robin

Этот класс реализует алгоритм, планируя волокна в круговом режиме.

#include <boost/fiber/algo/round_robin.hpp>
namespace boost {
namespace fibers {
namespace algo {
class round_robin : public algorithm {
    virtual void awakened( context *) noexcept;
    virtual context * pick_next() noexcept;
    virtual bool has_ready_fibers() const noexcept;
    virtual void suspend_until( std::chrono::steady_clock::time_point const&) noexcept;
    virtual void notify() noexcept;
};
}}}

Member function awakened()

virtual void awakened( context * f) noexcept;

Effects:

Очереди волокна f на готовую очередь.

Throws:

Ничего.

Member function pick_next()

virtual context * pick_next() noexcept;

Returns:

волокно во главе готовой очереди или nullptr, если очередь пуста.

Throws:

Ничего.

Note:

Размещая готовые волокна на хвосте очереди и возвращая их из головы этой очереди, делит нить между готовыми волокнами круговым способом.

Member function has_ready_fibers()

virtual bool has_ready_fibers() const noexcept;

Returns:

true, если планировщик имеет готовые к запуску волокна.

Throws:

Ничего.

Member function suspend_until()

virtual void suspend_until( std::chrono::steady_clock::time_point const& abs_time) noexcept;

Effects:

Сообщает round_robin, что готовое волокно не будет доступно до точки времени abs_time. Эта реализация блокирует в std::condition_variable::wait_until().

Throws:

Ничего.

Member function notify()

virtual void notify() noexcept = 0;

Effects:

Пробуждение ожидающего вызова round_robin::suspend_until(), некоторые волокна могут быть готовы. Эта реализация будит suspend_until() via std::condition_variable::notify_all().

Throws:

Ничего.

Class shared_work

Этот класс реализует алгоритм ; готовые волокна разделяются между всеми экземплярами (запущенными на разных нитях) Shared_work.

#include <boost/fiber/algo/shared_work.hpp>
namespace boost {
namespace fibers {
namespace algo {
class shared_work : public algorithm {
    virtual void awakened( context *) noexcept;
    virtual context * pick_next() noexcept;
    virtual bool has_ready_fibers() const noexcept;
    virtual void suspend_until( std::chrono::steady_clock::time_point const&) noexcept;
    virtual void notify() noexcept;
};
}}}

Member function awakened()

virtual void awakened( context * f) noexcept;

Effects:

Очереди волокна f на общую готовую очередь.

Throws:

Ничего.

Member function pick_next()

virtual context * pick_next() noexcept;

Returns:

волокно во главе готовой очереди или nullptr, если очередь пуста.

Throws:

Ничего.

Note:

Размещая готовые волокна на хвосте общей очереди и возвращая их из головы этой очереди, делит нить между готовыми волокнами круговым способом.

Member function has_ready_fibers()

virtual bool has_ready_fibers() const noexcept;

Returns:

true, если планировщик имеет готовые к запуску волокна.

Throws:

Ничего.

Member function suspend_until()

virtual void suspend_until( std::chrono::steady_clock::time_point const& abs_time) noexcept;

Effects:

Сообщает shared_work, что готовое волокно не будет доступно до точки времени abs_time. Эта реализация блокирует в std::condition_variable::wait_until().

Throws:

Ничего.

Member function notify()

virtual void notify() noexcept = 0;

Effects:

Пробуждение ожидающего вызова к shared_work::suspend_until(), некоторые волокна могут быть готовы. Эта реализация будит suspend_until() via std::condition_variable::notify_all().

Throws:

Ничего.

Custom Scheduler Fiber Properties

Класс планировщика, непосредственно полученный из алгоритма, может использовать любую информацию, доступную из контекста, для реализации интерфейса алгоритма. Но пользовательскому планировщику может потребоваться отслеживать дополнительные свойства волокна. Например, планировщику, основанному на приоритете, необходимо будет отслеживать приоритет волокна & # 8217.

Boost.Fiber обеспечивает механизм, с помощью которого ваш пользовательский планировщик может связывать пользовательские свойства с каждым волокном.

Class fiber_properties

Класс свойств волокна должен быть получен из fiber_properties.

#include <boost/fiber/properties.hpp>
namespace boost {
namespace fibers {
class fiber_properties {
public:
    fiber_properties( context *) noexcept;
    virtual ~fiber_properties();
protected:
    void notify() noexcept;
};
}}

Constructor

fiber_properties( context * f) noexcept;

Effects:

Конструирует компонент базового класса пользовательского подкласса.

Throws:

Ничего.

Note:

Конструктор подкласса должен принять контекст* и передать его конструатору базового класса fiber_properties.

Member function notify()

void notify() noexcept;

Effects:

Передайте управление на заказ algorithm_with_properties<> subclass’s algorithm_with_properties::property_change() method.

Throws:

Ничего.

Note:

Пользовательский планировщик’s алгоритм_с_свойствами::pick_next() метод может динамически выбирать из готовых волокон, или алгоритм_с_свойствами::awakened() может вместо этого вставлять каждое готовое волокно в некоторую форму готовой очереди для pick_next(). В последнем случае, если код приложения изменяет свойство волокна (например, приоритет), которое должно повлиять на отношение волокна & # 8217 к другим готовым волокнам, пользовательскому планировщику должна быть предоставлена возможность переупорядочения его готовой очереди. Подкласс пользовательского свойства должен реализовать способ доступа для изменения такого свойства; этот метод доступа должен вызывать уведомлять () после того, как новое значение свойства было сохранено. Это передает управление пользовательскому планировщику’s property_change() методу, позволяя пользовательскому планировщику соответствующим образом переупорядочивать свою готовую очередь. Используйте по своему усмотрению. Конечно, если вы определяете свойство, которое не влияет на поведение метода pick_next(), вам не нужно звонить уведомлять () при изменении этого свойства.

Template algorithm_with_properties<>

Пользовательский планировщик, который зависит от класса пользовательских свойств PROPS, должен быть получен из algorithm_with_properties<PROPS>. PROPS должен быть получен из fiber_properties.

#include <boost/fiber/algorithm.hpp>
namespace boost {
namespace fibers {
namespace algo {
template< typename PROPS >
struct algorithm_with_properties {
    virtual void awakened( context *, PROPS &) noexcept = 0;
    virtual context * pick_next() noexcept;
    virtual bool has_ready_fibers() const noexcept;
    virtual void suspend_until( std::chrono::steady_clock::time_point const&) noexcept = 0;
    virtual void notify() noexcept = 0;
    PROPS & properties( context *) noexcept;
    virtual void property_change( context *, PROPS &) noexcept;
    virtual fiber_properties * new_properties( context *);
};
}}}

Member function awakened()

virtual void awakened( context * f, PROPS & properties) noexcept;

Effects:

Информирует планировщик, что волокно f готово к запуску, как алгоритм::awakened(). Пропускает связанный с волокном’s экземпляр PROPS.

Throws:

Ничего.

Note:

Подкласс algorithm_with_properties<> должен переопределить этот метод вместо algorithm::awakened().

Member function pick_next()

virtual context * pick_next() noexcept;

Returns:

волокно, которое должно быть возобновлено следующим образом, или nullptr, если нет готового волокна.

Throws:

Ничего.

Note:

алгоритм::pick_next()

Member function has_ready_fibers()

virtual bool has_ready_fibers() const noexcept;

Returns:

true, если планировщик имеет готовые к запуску волокна.

Throws:

Ничего.

Note:

алгоритм::has_ready_fibers()

Member function suspend_until()

virtual void suspend_until( std::chrono::steady_clock::time_point const& abs_time) noexcept = 0;

Effects:

Информирует планировщик, что ни одно волокно не будет готово до точки времени abs_time.

Note:

алгоритм::suspend_until()

Member function notify()

virtual void notify() noexcept = 0;

Effects:

Просит планировщика вернуться с ожидающего вызова на алгоритм_with_properties::suspend_until().

Note:

алгоритм::notify()

Member function properties()

PROPS& properties( context * f) noexcept;

Returns:

экземпляр PROPS, связанный с волокном f.

Throws:

Ничего.

Note:

Связанный с волокном’ экземпляр PROPS уже передан algorithm_with_properties::awakened() и algorithm_with_properties::property_change(). Тем не менее, каждый подкласс алгоритм должен отслеживать набор готовых экземпляров контекст. Этот метод позволяет вашему пользовательскому планировщику извлекать экземпляр подкласса fiber_properties для любого контекста в его коллекции.

Member function property_change()

virtual void property_change( context * f, PROPS & properties) noexcept;

Effects:

Сообщите пользовательскому планировщику о возможно значимом изменении свойства, принадлежащего волокну f. свойства содержат новые значения всех соответствующих свойств.

Throws:

Ничего.

Note:

Этот метод называется только тогда, когда пользовательский подкласс fiber_properties явно вызывает fiber_properties::notify().

Member function new_properties()

virtual fiber_properties * new_properties( context * f);

Returns:

Новый экземпляр fiber_properties подкласса PROPS.

Note:

По умолчанию algorithm_with_properties<>::new_properties() просто возвращает newPROPS(f), помещая экземпляр PROPS на кучу. Переопределить этот способ для выделения PROPS каким-либо другим способом. Возвращенный указатель fiber_properties должен указывать на экземпляр PROPS, связанный с волокном f.

Class context

Хотя вы можете рассматривать контекст* как непрозрачный токен, некоторые члены контекст могут быть полезны для реализации пользовательского планировщика.

Особо следует отметить тот факт, что контекст содержит крючок для участия в буст::интрузивный::список<-- [ORIG_BEGIN]typedef’ed as boost::fibers::scheduler::ready_queue_t. This hook is reserved for use by algorithm implementations. (For instance, round_robin contains a ready_queue_t instance to manage its ready fibers.) See context::ready_is_linked(), context::ready_link(), context::ready_unlink(). [ORIG_END] -->

Ваша реализация алгоритм может использовать любой контейнер, которым вы хотите управлять, прошедшие экземпляры контекст. ready_queue_t позволяет избежать некоторых накладных расходов типичных контейнеров STL.

#include <boost/fiber/context.hpp>
namespace boost {
namespace fibers {
enum class type {
  none               = unspecified,
  main_context       = unspecified, // fiber associated with thread's stack
  dispatcher_context = unspecified, // special fiber for maintenance operations
  worker_context     = unspecified, // fiber not special to the library
  pinned_context     = unspecified  // fiber must not be migrated to another thread
};
class context {
public:
    class id;
    static context * active() noexcept;
    context( context const&) = delete;
    context & operator=( context const&) = delete;
    id get_id() const noexcept;
    void detach() noexcept;
    void attach( context *) noexcept;
    bool is_context( type) const noexcept;
    bool is_terminated() const noexcept;
    bool ready_is_linked() const noexcept;
    bool remote_ready_is_linked() const noexcept;
    bool wait_is_linked() const noexcept;
    template< typename List >
    void ready_link( List &) noexcept;
    template< typename List >
    void remote_ready_link( List &) noexcept;
    template< typename List >
    void wait_link( List &) noexcept;
    void ready_unlink() noexcept;
    void remote_ready_unlink() noexcept;
    void wait_unlink() noexcept;
    void suspend() noexcept;
    void set_ready( context *) noexcept;
};
bool operator<( context const& l, context const& r) noexcept;
}}

Static member function active()

static context * active() noexcept;

Returns:

Укажите на пример текущего волокна.

Throws:

Ничего

Member function get_id()

context::id get_id() const noexcept;

Returns:

Если * это относится к волокну исполнения, экземпляр волокно::id, который представляет это волокно. В противном случае возвращается построенный по умолчанию fiber::id.

Throws:

Ничего

See also:

fiber::get_id()

Member function attach()

void attach( context * f) noexcept;

Precondition:

this->get_scheduler() ==nullptr

Effects:

Прикрепите волокно f к планировщику, работающему *это.

Postcondition:

this->get_scheduler() != nullptr

Throws:

Ничего

Note:

Типичный вызов: boost::::context::active->attach(f);

Note:

f не должен быть контекстом работающего волокна’s. Он не должен быть заблокирован или прекращен. Он не должен быть pinned_context. В настоящее время он должен быть отделен. В настоящее время он не должен быть привязан к алгоритму реализации’s готовой очереди. Большинство из этих условий подразумевается, что f принадлежит реализации алгоритм, то есть он был передан алгоритм::пробужден(), но еще не был возвращен алгоритм::pick_next(). Как правило, реализация pick_next() будет называть attach() с контекстом*. Сначала необходимо удалить f из готовой очереди. Вы никогда не должны передавать pinned_context attach(), потому что вы никогда не должны были называть его detach().

Member function detach()

void detach() noexcept;

Precondition:

(this->get_scheduler()nullptr) && ! pinned_context

Effects:

Отсоедините волокно *this от его планировщика, работающего *this.

Throws:

Ничего

Postcondition:

this->get_scheduler() ==nullptr

Note:

Этот метод должен быть вызван нитью, с которой в настоящее время связано волокно. *Это не должно быть контекстом работающего волокна’s. Он не должен быть заблокирован или прекращен. Не должно быть pinned_context. Его уже нельзя отделять. Он не должен быть уже связан с алгоритмом реализации’s готовая очередь. Большинство из этих условий подразумевается *, что передается алгоритм::awakened(); реализация awakened() должна, однако, проверяться на pinned_context. Он должен вызывать detach()до, связывая * это в готовую очередь.

Note:

В частности, ошибочно пытаться мигрировать волокно из одной нити в другую, называя оба метода detach() и attach() в методе algorithm::pick_next(). pick_next() вызывается в потоке предполагаемого назначения. detach() должен быть вызван исходным потоком волокна’s. Вы должны позвонить detach() в соответствующем методе awakened().

Note:

Если вы не намерены сделать волокно доступным для потенциальной миграции в другую нить, вы не должны называть ни detach(), ни attach() с его контекстом.

Member function is_context()

bool is_context( type t) const noexcept;

Returns:

true, если * это имеет указанный тип.

Throws:

Ничего

Note:

type::worker_context здесь означает любое волокно, не специальное для библиотеки. Для type::main_context context связан с mainволокном резьбы: неявно созданным самим потоком Boost.Fiber.Для type::dispatcher_context context связан с dispatchingволокном, ответственным за отправку пробудившихся волокон в готовую очередь планировщика’. Оптоволокно dispatching является деталью реализации оптоволоконного менеджера. Контекст main или dispatching fiber — любое волокно, для которого is_context(pinned_context) является true — никогда не должно передаваться context::detach().

Member function is_terminated()

bool is_terminated() const noexcept;

Returns:

true, если * этот больше не является допустимым контекстом.

Throws:

Ничего

Note:

Контекст вернулся из своей оптоволоконной функции и больше не считается допустимым контекстом.

Member function ready_is_linked()

bool ready_is_linked() const noexcept;

Returns:

true, если * это хранится в алгоритме реализации’s готовой очереди.

Throws:

Ничего

Note:

В частности, этот метод указывает, был ли контекст::ready_link() вызван на *это. ready_is_linked() не имеет информации об участии в каких-либо других контейнерах.

Member function remote_ready_is_linked()

bool remote_ready_is_linked() const noexcept;

Returns:

true, если * это хранится в диспетчере волокон’s удаленной очереди.

Throws:

Ничего

Note:

контекст, сигнализированный как готовый другим потоком, сначала хранится в диспетчере волокон & #8217;s удаленной очереди. Это механизм, с помощью которого диспетчер волокон защищает реализацию алгоритма от поперечных вызовов алгоритма::awakened().

Member function wait_is_linked()

bool wait_is_linked() const noexcept;

Returns:

true, если * это хранится в очереди ожидания некоторого объекта синхронизации.

Throws:

Ничего

Note:

контекст волокна, ожидающего на объекте синхронизации (например, mutex, condition_variable и т.д.) хранится в очереди ожидания этого объекта синхронизации.

Member function ready_link()

template< typename List >
void ready_link( List & lst) noexcept;

Effects:

Хранит *это в готовой очереди lst.

Throws:

Ничего

Note:

Аргумент lst должен представлять собой двойной список из Boost.Intrusive, например, экземпляр boost::fibers::scheduler::ready_queue_t. В частности, он должен быть boost::intrusive::list совместим с list_member_hook, хранящимся в объекте context.

Member function remote_ready_link()

template< typename List >
void remote_ready_link( List & lst) noexcept;

Effects:

Хранит *это в готовой очереди lst.

Throws:

Ничего

Note:

Аргумент lst должен представлять собой двойной список из Boost.Intrusive.

Member function wait_link()

template< typename List >
void wait_link( List & lst) noexcept;

Effects:

Хранит *это в готовой очереди lst.

Throws:

Ничего

Note:

Аргумент lst должен представлять собой двойной список из Boost.Intrusive.

Member function ready_unlink()

void ready_unlink() noexcept;

Effects:

Удаляет *this из готовой очереди: отменяет эффект контекст::ready_link().

Throws:

Ничего

Member function remote_ready_unlink()

void remote_ready_unlink() noexcept;

Effects:

Удалите *this из удаленной очереди.

Throws:

Ничего

Member function wait_unlink()

void wait_unlink() noexcept;

Effects:

Удалить *это из очереди ожидания.

Throws:

Ничего

Member function suspend()

void suspend() noexcept;

Effects:

Приостанавливает работающее волокно (волокно, связанное с *this) до тех пор, пока некоторое другое волокно не пройдет this до контекст::set_ready(). *this помечается как неготовое, и управление переходит к планировщику, чтобы выбрать другое волокно для запуска.

Throws:

Ничего

Note:

Это низкоуровневый API, потенциально полезный для интеграции с другими фреймворками. Он не предназначен для непосредственного использования типичной прикладной программой.

Note:

Обязанностью абонента является организация вызова set_ready() с указателем на this в некоторое время в будущем.

Member function set_ready()

void set_ready( context * ctx ) noexcept;

Effects:

Отметьте волокно, связанное с контекстом *ctx, как готовое к работе. Это не сразу возобновляет это волокно; скорее оно передает волокно планировщику для последующего возобновления. Если планировщик простаивает (не вернулся с вызова на алгоритм::suspend_until()), алгоритм::notify() призван разбудить его.

Throws:

Ничего

Note:

Это низкоуровневый API, потенциально полезный для интеграции с другими фреймворками. Он не предназначен для непосредственного использования типичной прикладной программой.

Note:

Явно поддерживается вызов set_ready(ctx) из потока, отличного от того, на котором в настоящее время приостановлен *ctx. Соответствующее волокно будет возобновлено на исходной нити в надлежащее время.

Non-member function operator<()

bool operator<( context const& l, context const& r) noexcept;

Returns:

true, если l.get_id< r.get_id() является true, false в противном случае.

Throws:

Ничего.


PrevUpHomeNext

Статья Scheduling раздела Chapter 1. Fiber Chapter 1. Fiber может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Chapter 1. Fiber ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-19 19:39:42/0.017277002334595/1