]>
Commit | Line | Data |
---|---|---|
1 | .\" Copyright (c) 2008-2012 Apple Inc. All rights reserved. | |
2 | .Dd May 1, 2008 | |
3 | .Dt dispatch_queue_create 3 | |
4 | .Os Darwin | |
5 | .Sh NAME | |
6 | .Nm dispatch_queue_create , | |
7 | .Nm dispatch_queue_get_label , | |
8 | .Nm dispatch_get_current_queue , | |
9 | .Nm dispatch_get_global_queue , | |
10 | .Nm dispatch_get_main_queue , | |
11 | .Nm dispatch_main , | |
12 | .Nm dispatch_set_target_queue | |
13 | .Nd where blocks are scheduled for execution | |
14 | .Sh SYNOPSIS | |
15 | .Fd #include <dispatch/dispatch.h> | |
16 | .Ft dispatch_queue_t | |
17 | .Fo dispatch_queue_create | |
18 | .Fa "const char *label" "dispatch_queue_attr_t attr" | |
19 | .Fc | |
20 | .Ft "const char *" | |
21 | .Fo dispatch_queue_get_label | |
22 | .Fa "dispatch_queue_t queue" | |
23 | .Fc | |
24 | .Ft dispatch_queue_t | |
25 | .Fo dispatch_get_global_queue | |
26 | .Fa "long priority" | |
27 | .Fa "unsigned long flags" | |
28 | .Fc | |
29 | .Ft dispatch_queue_t | |
30 | .Fo dispatch_get_main_queue | |
31 | .Fa void | |
32 | .Fc | |
33 | .Ft void | |
34 | .Fo dispatch_main | |
35 | .Fa void | |
36 | .Fc | |
37 | .Ft void | |
38 | .Fo dispatch_set_target_queue | |
39 | .Fa "dispatch_object_t object" | |
40 | .Fa "dispatch_queue_t target" | |
41 | .Fc | |
42 | .Sh DESCRIPTION | |
43 | Queues are the fundamental mechanism for scheduling blocks for execution within | |
44 | the | |
45 | .Xr dispatch 3 | |
46 | framework. | |
47 | .Pp | |
48 | All blocks submitted to dispatch queues are dequeued in FIFO order. | |
49 | Queues created with the | |
50 | .Dv DISPATCH_QUEUE_SERIAL | |
51 | attribute wait for the previously dequeued block to complete before dequeuing | |
52 | the next block. A queue with this FIFO completion behavior is usually simply | |
53 | described as a "serial queue." All memory writes performed by a block dispatched | |
54 | to a serial queue are guaranteed to be visible to subsequent blocks dispatched | |
55 | to the same queue. Queues are not bound to any specific thread of execution and | |
56 | blocks submitted to independent queues may execute concurrently. | |
57 | .Pp | |
58 | Queues created with the | |
59 | .Dv DISPATCH_QUEUE_CONCURRENT | |
60 | attribute may execute dequeued blocks concurrently and support barrier blocks | |
61 | submitted with the dispatch barrier API. | |
62 | .Sh CREATION | |
63 | Queues are created with the | |
64 | .Fn dispatch_queue_create | |
65 | function. Queues, like all dispatch objects, are reference counted and newly | |
66 | created queues have a reference count of one. | |
67 | .Pp | |
68 | The optional | |
69 | .Fa label | |
70 | argument is used to describe the purpose of the queue and is useful during | |
71 | debugging and performance analysis. If a label is provided, it is copied. | |
72 | By convention, clients should pass a reverse DNS style label. For example: | |
73 | .Pp | |
74 | .Bd -literal -offset indent | |
75 | my_queue = dispatch_queue_create("com.example.subsystem.taskXYZ", | |
76 | DISPATCH_QUEUE_SERIAL); | |
77 | .Ed | |
78 | .Pp | |
79 | The | |
80 | .Fa attr | |
81 | argument specifies the type of queue to create and must be either | |
82 | .Dv DISPATCH_QUEUE_SERIAL | |
83 | or | |
84 | .Dv DISPATCH_QUEUE_CONCURRENT . | |
85 | .Pp | |
86 | The | |
87 | .Fn dispatch_queue_get_label | |
88 | function returns the label provided when the given | |
89 | .Fa queue | |
90 | was created (or an empty C string if no label was provided at creation). | |
91 | Passing the constant | |
92 | .Dv DISPATCH_CURRENT_QUEUE_LABEL | |
93 | to | |
94 | .Fn dispatch_queue_get_label | |
95 | returns the label of the current queue. | |
96 | .Sh SUSPENSION | |
97 | Queues may be temporarily suspended and resumed with the functions | |
98 | .Fn dispatch_suspend | |
99 | and | |
100 | .Fn dispatch_resume | |
101 | respectively. Suspension is checked prior to block execution and is | |
102 | .Em not | |
103 | preemptive. | |
104 | .Sh MAIN QUEUE | |
105 | The dispatch framework provides a default serial queue for the application to | |
106 | use. This queue is accessed via the | |
107 | .Fn dispatch_get_main_queue | |
108 | function. | |
109 | .Pp | |
110 | Programs must call | |
111 | .Fn dispatch_main | |
112 | at the end of | |
113 | .Fn main | |
114 | in order to process blocks submitted to the main queue. (See the | |
115 | .Sx COMPATIBILITY | |
116 | section for exceptions.) The | |
117 | .Fn dispatch_main | |
118 | function never returns. | |
119 | .Sh GLOBAL CONCURRENT QUEUES | |
120 | Unlike the main queue or queues allocated with | |
121 | .Fn dispatch_queue_create , | |
122 | the global concurrent queues schedule blocks as soon as threads become | |
123 | available (non-FIFO completion order). Four global concurrent queues are | |
124 | provided, representing the following priority bands: | |
125 | .Bl -bullet -compact -offset indent | |
126 | .It | |
127 | DISPATCH_QUEUE_PRIORITY_HIGH | |
128 | .It | |
129 | DISPATCH_QUEUE_PRIORITY_DEFAULT | |
130 | .It | |
131 | DISPATCH_QUEUE_PRIORITY_LOW | |
132 | .It | |
133 | DISPATCH_QUEUE_PRIORITY_BACKGROUND | |
134 | .El | |
135 | .Pp | |
136 | The priority of a global concurrent queue controls the scheduling priority of | |
137 | the threads created by the system to invoke the blocks submitted to that queue. | |
138 | Global queues with lower priority will be scheduled for execution after all | |
139 | global queues with higher priority have been scheduled. Additionally, items on | |
140 | the background priority global queue will execute on threads with background | |
141 | state as described in | |
142 | .Xr setpriority 2 | |
143 | (i.e.\& disk I/O is throttled and the thread's scheduling priority is set to | |
144 | lowest value). | |
145 | .Pp | |
146 | Use the | |
147 | .Fn dispatch_get_global_queue | |
148 | function to obtain the global queue of given priority. The | |
149 | .Fa flags | |
150 | argument is reserved for future use and must be zero. Passing any value other | |
151 | than zero may result in a NULL return value. | |
152 | .Sh TARGET QUEUE | |
153 | The | |
154 | .Fn dispatch_set_target_queue | |
155 | function updates the target queue of the given dispatch object. The target | |
156 | queue of an object is responsible for processing the object. | |
157 | .Pp | |
158 | The new target queue is retained by the given object before the previous target | |
159 | queue is released. The new target queue setting will take effect between block | |
160 | executions on the object, but not in the middle of any existing block executions | |
161 | (non-preemptive). | |
162 | .Pp | |
163 | The default target queue of all dispatch objects created by the application is | |
164 | the default priority global concurrent queue. To reset an object's target queue | |
165 | to the default, pass the | |
166 | .Dv DISPATCH_TARGET_QUEUE_DEFAULT | |
167 | constant to | |
168 | .Fn dispatch_set_target_queue . | |
169 | .Pp | |
170 | The priority of a dispatch queue is inherited from its target queue. | |
171 | In order to change the priority of a queue created with | |
172 | .Fn dispatch_queue_create , | |
173 | use the | |
174 | .Fn dispatch_get_global_queue | |
175 | function to obtain a target queue of the desired priority. | |
176 | .Pp | |
177 | Blocks submitted to a serial queue whose target queue is another serial queue | |
178 | will not be invoked concurrently with blocks submitted to the target queue or | |
179 | to any other queue with that same target queue. | |
180 | .Pp | |
181 | The target queue of a dispatch source specifies where its event handler and | |
182 | cancellation handler blocks will be submitted. See | |
183 | .Xr dispatch_source_create 3 | |
184 | for more information about dispatch sources. | |
185 | .Pp | |
186 | The target queue of a dispatch I/O channel specifies the priority of the global | |
187 | queue where its I/O operations are executed. See | |
188 | .Xr dispatch_io_create 3 | |
189 | for more information about dispatch I/O channels. | |
190 | .Pp | |
191 | For all other dispatch object types, the only function of the target queue is | |
192 | to determine where an object's finalizer function is invoked. | |
193 | .Pp | |
194 | The result of passing the main queue or a global concurrent queue as the first | |
195 | argument of | |
196 | .Fn dispatch_set_target_queue | |
197 | is undefined. | |
198 | .Pp | |
199 | Directly or indirectly setting the target queue of a dispatch queue to itself is | |
200 | undefined. | |
201 | .Sh DEPRECATED FUNCTIONS | |
202 | The following functions are deprecated and will be removed in a future release: | |
203 | .Bl -item | |
204 | .It | |
205 | .Ft dispatch_queue_t | |
206 | .Fn dispatch_get_current_queue void ; | |
207 | .El | |
208 | .Pp | |
209 | .Fn dispatch_get_current_queue | |
210 | always returns a valid queue. When called from within a block | |
211 | submitted to a dispatch queue, that queue will be returned. If this function is | |
212 | called from the main thread before | |
213 | .Fn dispatch_main | |
214 | is called, then the result of | |
215 | .Fn dispatch_get_main_queue | |
216 | is returned. In all other cases, the default target queue will be returned. | |
217 | .Pp | |
218 | The use of | |
219 | .Fn dispatch_get_current_queue | |
220 | is strongly discouraged except for debugging and logging purposes. Code must not | |
221 | make any assumptions about the queue returned, unless it is one of the global | |
222 | queues or a queue the code has itself created. The returned queue may have | |
223 | arbitrary policies that may surprise code that tries to schedule work with the | |
224 | queue. The list of policies includes, but is not limited to, queue width (i.e. | |
225 | serial vs. concurrent), scheduling priority, security credential or filesystem | |
226 | configuration. This function is deprecated and will be removed in a future | |
227 | release. | |
228 | .Pp | |
229 | It is equally unsafe for code to assume that synchronous execution onto a queue | |
230 | is safe from deadlock if that queue is not the one returned by | |
231 | .Fn dispatch_get_current_queue . | |
232 | .Pp | |
233 | The result of | |
234 | .Fn dispatch_get_main_queue | |
235 | may or may not equal the result of | |
236 | .Fn dispatch_get_current_queue | |
237 | when called on the main thread. Comparing the two is not a valid way to test | |
238 | whether code is executing on the main thread. Foundation/AppKit programs should | |
239 | use [NSThread isMainThread]. POSIX programs may use | |
240 | .Xr pthread_main_np 3 . | |
241 | .Pp | |
242 | .Fn dispatch_get_current_queue | |
243 | may return a queue owned by a different subsystem which has already had all | |
244 | external references to it released. While such a queue will continue to exist | |
245 | until all blocks submitted to it have completed, attempting to retain it is | |
246 | forbidden and will trigger an assertion. If Objective-C Automatic Reference | |
247 | Counting is enabled, any use of the object returned by | |
248 | .Fn dispatch_get_current_queue | |
249 | will cause retain calls to be automatically generated, so the use of | |
250 | .Fn dispatch_get_current_queue | |
251 | for any reason in code built with ARC is particularly strongly discouraged. | |
252 | .Sh COMPATIBILITY | |
253 | Cocoa applications need not call | |
254 | .Fn dispatch_main . | |
255 | Blocks submitted to the main queue will be executed as part of the "common | |
256 | modes" of the application's main NSRunLoop or CFRunLoop. | |
257 | However, blocks submitted to the main queue in applications using | |
258 | .Fn dispatch_main | |
259 | are not guaranteed to execute on the main thread. | |
260 | .Pp | |
261 | The dispatch framework is a pure C level API. As a result, it does not catch | |
262 | exceptions generated by higher level languages such as Objective-C or C++. | |
263 | Applications | |
264 | .Em MUST | |
265 | catch all exceptions before returning from a block submitted to a dispatch | |
266 | queue; otherwise the process will be terminated with an uncaught exception. | |
267 | .Pp | |
268 | The dispatch framework manages the relationship between dispatch queues and | |
269 | threads of execution. As a result, applications | |
270 | .Em MUST NOT | |
271 | delete or mutate objects that they did not create. The following interfaces | |
272 | .Em MUST NOT | |
273 | be called by blocks submitted to a dispatch queue: | |
274 | .Bl -bullet -offset indent | |
275 | .It | |
276 | .Fn pthread_cancel | |
277 | .It | |
278 | .Fn pthread_detach | |
279 | .It | |
280 | .Fn pthread_join | |
281 | .It | |
282 | .Fn pthread_kill | |
283 | .It | |
284 | .Fn pthread_exit | |
285 | .El | |
286 | .Pp | |
287 | Applications | |
288 | .Em MAY | |
289 | call the following interfaces from a block submitted to a dispatch queue if | |
290 | and only if they restore the thread to its original state before returning: | |
291 | .Bl -bullet -offset indent | |
292 | .It | |
293 | .Fn pthread_setcancelstate | |
294 | .It | |
295 | .Fn pthread_setcanceltype | |
296 | .It | |
297 | .Fn pthread_setschedparam | |
298 | .It | |
299 | .Fn pthread_sigmask | |
300 | .It | |
301 | .Fn pthread_setugid_np | |
302 | .El | |
303 | .Pp | |
304 | Applications | |
305 | .Em MUST NOT | |
306 | rely on the following interfaces returning predictable results between | |
307 | invocations of blocks submitted to a dispatch queue: | |
308 | .Bl -bullet -offset indent | |
309 | .It | |
310 | .Fn pthread_self | |
311 | .It | |
312 | .Fn pthread_getschedparam | |
313 | .It | |
314 | .Fn pthread_get_stacksize_np | |
315 | .It | |
316 | .Fn pthread_get_stackaddr_np | |
317 | .It | |
318 | .Fn pthread_mach_thread_np | |
319 | .It | |
320 | .Fn pthread_from_mach_thread_np | |
321 | .El | |
322 | .Pp | |
323 | While the result of | |
324 | .Fn pthread_self | |
325 | may change between invocations of blocks, the value will not change during the | |
326 | execution of any single block. Because the underlying thread may change beteween | |
327 | block invocations on a single queue, using per-thread data as an out-of-band | |
328 | return value is error prone. In other words, the result of calling | |
329 | .Fn pthread_setspecific | |
330 | and | |
331 | .Fn pthread_getspecific | |
332 | is well defined within a signle block, but not across multiple blocks. Also, | |
333 | one cannot make any assumptions about when the destructor passed to | |
334 | .Fn pthread_key_create | |
335 | is called. The destructor may be called between the invocation of blocks on | |
336 | the same queue, or during the idle state of a process. | |
337 | .Pp | |
338 | The following example code correctly handles per-thread return values: | |
339 | .Bd -literal -offset indent | |
340 | __block int r; | |
341 | __block int e; | |
342 | dispatch_sync(queue, ^{ | |
343 | r = kill(1, 0); | |
344 | // Copy the per-thread return value to the callee thread | |
345 | e = errno; | |
346 | }); | |
347 | printf("kill(1,0) returned %d and errno %d\n", r, e); | |
348 | .Ed | |
349 | .Pp | |
350 | Note that in the above example | |
351 | .Va errno | |
352 | is a per-thread variable and must be copied out explicitly as the block may be | |
353 | invoked on different thread of execution than the caller. Another example of | |
354 | per-thread data that would need to be copied is the use of | |
355 | .Fn getpwnam | |
356 | instead of | |
357 | .Fn getpwnam_r . | |
358 | .Pp | |
359 | As an optimization, | |
360 | .Fn dispatch_sync | |
361 | invokes the block on the current thread when possible. In this case, the thread | |
362 | specific data such as | |
363 | .Va errno | |
364 | may persist from the block until back to the caller. Great care should be taken | |
365 | not to accidentally rely on this side-effect. | |
366 | .Pp | |
367 | .Sh SEE ALSO | |
368 | .Xr dispatch 3 , | |
369 | .Xr dispatch_async 3 , | |
370 | .Xr dispatch_object 3 , | |
371 | .Xr dispatch_source_create 3 |