BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdlmt.h
Go to the documentation of this file.
1
/// @file bdlmt.h
2
///
3
///
4
/// @defgroup bdlmt Package bdlmt
5
/// @brief Basic Development Library Multi Thread (bdlmt)
6
/// @addtogroup bdl
7
/// @{
8
/// @addtogroup bdlmt
9
/// @{
10
/// * <a href="#bdlmt-purpose"> Purpose</a>
11
/// * <a href="#bdlmt-mnemonic"> Mnemonic </a>
12
/// * <a href="#bdlmt-description"> Description </a>
13
/// * <a href="#bdlmt-hierarchical-synopsis"> Hierarchical Synopsis </a>
14
/// * <a href="#bdlmt-component-synopsis"> Component Synopsis </a>
15
/// * <a href="#bdlmt-generic-overview-of-thread-pools"> Generic Overview of Thread Pools </a>
16
/// * <a href="#bdlmt-synchronous-signals-on-unix"> Synchronous Signals on Unix </a>
17
///
18
/// # Purpose {#bdlmt-purpose}
19
/// Provides thread pools and event schedulers.
20
///
21
/// # Mnemonic {#bdlmt-mnemonic}
22
/// Basic Development Library Multi Thread (bdlmt)
23
///
24
/// @see bdlcc
25
///
26
/// # Description {#bdlmt-description}
27
/// The 'bdlmt' ("Basic Development Library Multi Thread") package
28
/// provides components for creating and managing thread pools, and components for
29
/// scheduling (time-based) events.
30
///
31
/// A "thread pool" is a collection of processor threads that are managed
32
/// together and used interchangeably to support user requests. The
33
/// @ref bdlmt_threadpool component allows clients to configure the pool so that it
34
/// grows and shrinks according to user demand, manage thread availability, and
35
/// schedule client "jobs" to be run independently as threads in the pool become
36
/// available. It does this by placing client requests on an internal job
37
/// queue, and controlling multiple threads as they remove jobs from the queue
38
/// and execute them.
39
///
40
/// A "multi-queue thread pool" defines a dynamic, configurable pool of queues,
41
/// each of which is processed by a thread in a thread pool, such that elements
42
/// on a given queue are processed serially, regardless of which thread is
43
/// processing the queue at a given time. In addition to the ability to create
44
/// and delete queues, clients are able to tune the underlying thread pool.
45
///
46
/// A "timer-event scheduler" defines a thread-safe event scheduler. It
47
/// provides methods to schedule and cancel recurring and non-recurring events
48
/// (also referred to as clock). The callbacks are processed by a separate
49
/// thread (called dispatcher thread).
50
///
51
/// ## Hierarchical Synopsis {#bdlmt-hierarchical-synopsis}
52
///
53
/// The 'bdlmt' package currently has 9 components having 2 levels of physical
54
/// dependency. The list below shows the hierarchical ordering of the components.
55
/// The order of components within each level is not architecturally significant,
56
/// just alphabetical.
57
/// @code
58
/// 2. bdlmt_multiqueuethreadpool
59
/// bdlmt_threadmultiplexor
60
///
61
/// 1. bdlmt_eventscheduler
62
/// bdlmt_fixedthreadpool
63
/// bdlmt_multiprioritythreadpool
64
/// bdlmt_signaler
65
/// bdlmt_threadpool
66
/// bdlmt_throttle
67
/// bdlmt_timereventscheduler
68
/// @endcode
69
///
70
/// ## Component Synopsis {#bdlmt-component-synopsis}
71
///
72
/// @ref bdlmt_eventscheduler :
73
/// Provide a thread-safe recurring and one-time event scheduler.
74
///
75
/// @ref bdlmt_fixedthreadpool :
76
/// Provide portable implementation for a fixed-size pool of threads.
77
///
78
/// @ref bdlmt_multiprioritythreadpool :
79
/// Provide a mechanism to parallelize a prioritized sequence of jobs.
80
///
81
/// @ref bdlmt_multiqueuethreadpool :
82
/// Provide a pool of queues, each processed serially by a thread pool.
83
///
84
/// @ref bdlmt_signaler :
85
/// Provide an implementation of a managed signals and slots system.
86
///
87
/// @ref bdlmt_threadmultiplexor :
88
/// Provide a mechanism for partitioning a collection of threads.
89
///
90
/// @ref bdlmt_threadpool :
91
/// Provide portable implementation for a dynamic pool of threads.
92
///
93
/// @ref bdlmt_throttle :
94
/// Provide mechanism for limiting the rate at which actions may occur.
95
///
96
/// @ref bdlmt_timereventscheduler :
97
/// Provide a thread-safe recurring and non-recurring event scheduler.
98
///
99
/// ## Generic Overview of Thread Pools {#bdlmt-generic-overview-of-thread-pools}
100
///
101
/// At the current time, this generic overview applies only to the
102
/// 'bdlmt_MultipriorityThreadPool'. The plan is for other threadpools to move
103
/// to this model at a later date.
104
///
105
/// As Figure 1 illustrates, a threadpool allows its clients to enqueue units of
106
/// work to be processed concurrently in multiple threads. Each work item, or
107
/// "job", consists of a function along with the address of its associated input
108
/// data. When executed, this address is supplied to the function as its only
109
/// argument; note that this function must have external linkage and return
110
/// 'void':
111
/// @code
112
/// extern "C" void job(void *); // Idiomatic C-style function signature
113
/// @endcode
114
/// Alternatively both the function and its data can be encapsulated and
115
/// supplied in the form of an (invokable) function object, or "functor", taking
116
/// no arguments and returning 'void'.
117
/// @code
118
/// +-------------------------------------------------------------------------+
119
/// | ThreadPool *Control* Methods |
120
/// | |
121
/// | Front Operations Middle Operations Back Operations |
122
/// | ---------------- ----------------- --------------- |
123
/// | int startThreads() void removeJobs() void enableQueue() |
124
/// | void stopThreads() void drainJobs() void disableQueue() |
125
/// | int resumeProcessing() int enqueueJob(func,arg) |
126
/// | int suspendProcessing() int enqueueJob(job) |
127
/// | |
128
/// +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+
129
/// | +--<--+--<--+--<--+--<--+--<--+----------------+ |
130
/// | | | | | | | | |
131
/// | Front <==| Job | Job | Job | Job | Job | |==< Back |
132
/// | | | | | | | | |
133
/// | +--<--+--<--+--<--+--<--+--<--+----------------+ |
134
/// | |
135
/// | ,----------------. ,-----------------. |
136
/// | ( N Worker Threads ) ( Thread Attributes ) |
137
/// | `----------------' `-----------------' |
138
/// +-------------------------------------------------------------------------+
139
/// Figure 1: Illustration of Generalized Thread Pool
140
/// @endcode
141
/// In addition to enqueuing jobs, a thread pool must supply primitive control
142
/// functionality such as creating and destroying worker threads, enabling and
143
/// disabling the enqueuing of new jobs, causing the queue to block until there
144
/// are no pending jobs, and removing (i.e., canceling) all pending (i.e., not
145
/// yet running) jobs. Different kinds of threadpools will provide different
146
/// functionality and/or performance characteristics, corresponding those of the
147
/// underlying thread-enabled ('bdlcc') queue -- e.g., (limited-capacity)
148
/// 'FixedQueue', (heap-based) 'PriorityQueue', and (array-based)
149
/// 'MultipriorityQueue'. Nonetheless, each of the threadpool objects in 'bdlmt'
150
/// should provide a suite of input and control operations that are consistent
151
/// in both name and behavior across the 'bdlmt' package.
152
///
153
/// Due to the intricate nature of threadpools, it is easy to convolve behaviors
154
/// in subtly different ways for functions having the same name. Consider, for
155
/// example, the method 'void drainJobs()', the basic functionality of which is
156
/// to 'block' the caller until all of the pending jobs complete (i.e., the
157
/// queue is empty and all worker threads are idle). Should 'drainJobs()' also
158
/// leave the queue in the disabled state? Even if that is a common usage
159
/// pattern, it is often useful to start with simple, orthogonal behaviors, and
160
/// if needed, define more complex behaviors in terms of them.
161
///
162
/// In the case of a thread pool, it is instructive to break the functionality
163
/// into three categories of operations relative to the underlying queue: Front,
164
/// Middle, and Back. At the back of the queue (refer to Figure 1), we need to
165
/// enable/disable clients from adding work items. Enabling or disabling the
166
/// queue does not affect the items already in the queue [Middle], nor any
167
/// worker threads processing these items [Front].
168
///
169
/// In the middle of the queue, we have two operations that result in purging
170
/// all pending items in the queue: 'drainJobs()' and 'removeJobs()' If we
171
/// invoke 'removeJobs()', then all currently pending (i.e., not started) work
172
/// items will be removed (i.e., canceled). During this process, clients
173
/// attempting to add work items [Back] will block, but their eventual success
174
/// or failure, (which is based solely on whether the queue is enabled or
175
/// disabled) is not affected. Note that jobs that are already in progress
176
/// [Front] are also unaffected. Similarly, invoking our orthogonal
177
/// 'drainJobs()' method will block enqueuing clients until all pending jobs
178
/// have completed, but will not affect the enabledness of the thread pool
179
/// [Back], nor the processing of work items [Front].
180
///
181
/// Finally we come to the front of the queue, which addresses the processing of
182
/// jobs. A (typically fixed) number of worker threads is specified at
183
/// construction. The thread pool "wakes up" in an enabled state, but without
184
/// having created the worker threads. Invoking the 'startThreads()' method
185
/// attempts to create these threads (unless they are already created). The
186
/// 'startThreads()' method returns 0 if all of these threads are started, and a
187
/// non-zero value otherwise (in which case none of the worker threads are
188
/// started). Redundant calls to 'startThreads()' do nothing and return zero.
189
/// Invoking 'stopThreads()' destroys each worker thread (after it completes any
190
/// current job). Note that the current contents of the queue [Middle], and the
191
/// ability to enqueue new jobs [Back] are not affected.
192
///
193
/// Whether or not started threads should be pulling jobs from the queue and
194
/// processing them is not necessarily the same as having the user-specified
195
/// number of worker threads created. In addition to being *enabled* and
196
/// *started* let's consider one more possible state, *suspended*. If a thread
197
/// pool is in the *suspended* state, then even when it is in the *started*
198
/// state, it will not attempt to pop jobs from the queue and execute them.
199
///
200
/// A created threadpool will be created enabled, not suspended, and not
201
/// started. All three of these qualities are orthogonal and any one of them
202
/// can be changed at any time.
203
///
204
/// The vast majority of users will be uninterested in both the 'suspend' and
205
/// 'disable' features, so it is imperative that newly created threadpools be
206
/// both non-suspended and enabled so users can remain blissfully ignorant of
207
/// them. It is also important the first usage examples, if not all of them,
208
/// omit use of these features to minimize learning time for the typical user.
209
///
210
/// To conclude this generic overview, we note that there is one common usage
211
/// that, although not minimal, arguably deserves to be a method of every thread
212
/// pool class: 'void shutdown()'. This method is best described as a
213
/// composition of the simple, orthogonal functions described above. In order
214
/// to shut down a thread pool, we need to first disable the enqueuing of any
215
/// additional jobs, then remove all of the pending work items, and finally stop
216
/// all of the active threads:
217
/// @code
218
/// void shutdown()
219
/// {
220
/// disableQueue();
221
/// removeJobs();
222
/// stopThreads();
223
/// }
224
/// @endcode
225
/// By making sure that our initial operations are simple and orthogonal, we can
226
/// ensure that the precise meaning of more complex operations is kept clear.
227
///
228
/// ## Synchronous Signals on Unix {#bdlmt-synchronous-signals-on-unix}
229
///
230
/// A thread pool ensures that, on Unix platforms, all the threads in the pool
231
/// block all asynchronous signals. Specifically all the signals, except the
232
/// following synchronous signals are blocked.
233
/// @code
234
/// SIGBUS
235
/// SIGFPE
236
/// SIGILL
237
/// SIGSEGV
238
/// SIGSYS
239
/// SIGABRT
240
/// SIGTRAP
241
/// SIGIOT
242
/// @endcode
243
///
244
/// @}
245
/** @} */
doxygen_input
bde
groups
bdl
bdlmt
doc
bdlmt.h
Generated by
1.9.8