Blame view

3rdparty/boost_1_81_0/libs/fiber/doc/customization.qbk 5.12 KB
977ed18d   Hu Chunming   提交三方库
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
  [/
            Copyright Oliver Kowalke 2013.
   Distributed under the Boost Software License, Version 1.0.
      (See accompanying file LICENSE_1_0.txt or copy at
            http://www.boost.org/LICENSE_1_0.txt
  ]
  
  [/ import path is relative to this .qbk file]
  [import ../examples/priority.cpp]
  
  [#custom]
  [section:custom Customization]
  
  [heading Overview]
  
  As noted in the [link scheduling Scheduling] section, by default
  __boost_fiber__ uses its own [class_link round_robin] scheduler for each
  thread. To control the way __boost_fiber__ schedules ready fibers on a
  particular thread, in general you must follow several steps. This section
  discusses those steps, whereas [link scheduling Scheduling] serves as a
  reference for the classes involved.
  
  The library's fiber manager keeps track of suspended (blocked) fibers. Only
  when a fiber becomes ready to run is it passed to the scheduler. Of course, if
  there are fewer than two ready fibers, the scheduler's job is trivial. Only
  when there are two or more ready fibers does the particular scheduler
  implementation start to influence the overall sequence of fiber execution.
  
  In this section we illustrate a simple custom scheduler that honors an integer
  fiber priority. We will implement it such that a fiber with higher priority is
  preferred over a fiber with lower priority. Any fibers with equal priority
  values are serviced on a round-robin basis.
  
  [/ @path link is relative to (eventual) doc/html/index.html, hence ../..]
  The full source code for the examples below is found in
  [@../../examples/priority.cpp priority.cpp].
  
  [heading Custom Property Class]
  
  The first essential point is that we must associate an integer priority with
  each fiber.[footnote A previous version of the Fiber library implicitly
  tracked an int priority for each fiber, even though the default scheduler
  ignored it. This has been dropped, since the library now supports arbitrary
  scheduler-specific fiber properties.]
  
  One might suggest deriving a custom [class_link fiber] subclass to store such
  properties. There are a couple of reasons for the present mechanism.
  
  # __boost_fiber__ provides a number of different ways to launch a fiber.
    (Consider [ns_function_link fibers..async].) Higher-level libraries might
    introduce additional such wrapper functions. A custom scheduler must
    associate its custom properties with ['every] fiber in the thread, not only
    the ones explicitly launched by instantiating a custom `fiber` subclass.
  # Consider a large existing program that launches fibers in many different
    places in the code. We discover a need to introduce a custom scheduler for a
    particular thread. If supporting that scheduler's custom properties required
    a particular `fiber` subclass, we would have to hunt down and modify every
    place that launches a fiber on that thread.
  # The [class_link fiber] class is actually just a handle to internal
    [class_link context] data. A subclass of `fiber` would not add data to
    `context`.
  
  The present mechanism allows you to ["drop in] a custom scheduler with its
  attendant custom properties ['without] altering the rest of your application.
  
  Instead of deriving a custom scheduler fiber properties subclass from
  [class_link fiber], you must instead derive it from [class_link
  fiber_properties].
  
  [priority_props]
  
  [heading Custom Scheduler Class]
  
  Now we can derive a custom scheduler from [template_link
  algorithm_with_properties], specifying our custom property class
  `priority_props` as the template parameter.
  
  [priority_scheduler]
  
  Our example `priority_scheduler` doesn't override [member_link
  algorithm_with_properties..new_properties]: we're content with
  allocating `priority_props` instances on the heap.
  
  [heading Replace Default Scheduler]
  
  You must call [function_link use_scheduling_algorithm] at the start of each
  thread on which you want __boost_fiber__ to use your custom scheduler rather
  than its own default [class_link round_robin]. Specifically, you must call
  `use_scheduling_algorithm()` before performing any other __boost_fiber__
  operations on that thread.
  
  [main]
  
  [heading Use Properties]
  
  The running fiber can access its own [class_link fiber_properties] subclass
  instance by calling [ns_function_link this_fiber..properties]. Although
  `properties<>()` is a nullary function, you must pass, as a template
  parameter, the `fiber_properties` subclass.
  
  [main_name]
  
  Given a [class_link fiber] instance still connected with a running fiber (that
  is, not [member_link fiber..detach]ed), you may access that fiber's properties
  using [template_member_link fiber..properties]. As with
  `boost::this_fiber::properties<>()`, you must pass your `fiber_properties` subclass
  as the template parameter.
  
  [launch]
  
  Launching a new fiber schedules that fiber as ready, but does ['not]
  immediately enter its ['fiber-function]. The current fiber retains control
  until it blocks (or yields, or terminates) for some other reason. As shown in
  the `launch()` function above, it is reasonable to launch a fiber and
  immediately set relevant properties -- such as, for instance, its priority.
  Your custom scheduler can then make use of this information next time the
  fiber manager calls [member_link algorithm_with_properties..pick_next].
  
  [endsect]