Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
372 lines
12 KiB
Groff
372 lines
12 KiB
Groff
.\" Copyright (c) 2008-2012 Apple Inc. All rights reserved.
|
|
.Dd May 1, 2008
|
|
.Dt dispatch_queue_create 3
|
|
.Os Darwin
|
|
.Sh NAME
|
|
.Nm dispatch_queue_create ,
|
|
.Nm dispatch_queue_get_label ,
|
|
.Nm dispatch_get_current_queue ,
|
|
.Nm dispatch_get_global_queue ,
|
|
.Nm dispatch_get_main_queue ,
|
|
.Nm dispatch_main ,
|
|
.Nm dispatch_set_target_queue
|
|
.Nd where blocks are scheduled for execution
|
|
.Sh SYNOPSIS
|
|
.Fd #include <dispatch/dispatch.h>
|
|
.Ft dispatch_queue_t
|
|
.Fo dispatch_queue_create
|
|
.Fa "const char *label" "dispatch_queue_attr_t attr"
|
|
.Fc
|
|
.Ft "const char *"
|
|
.Fo dispatch_queue_get_label
|
|
.Fa "dispatch_queue_t queue"
|
|
.Fc
|
|
.Ft dispatch_queue_t
|
|
.Fo dispatch_get_global_queue
|
|
.Fa "long priority"
|
|
.Fa "unsigned long flags"
|
|
.Fc
|
|
.Ft dispatch_queue_t
|
|
.Fo dispatch_get_main_queue
|
|
.Fa void
|
|
.Fc
|
|
.Ft void
|
|
.Fo dispatch_main
|
|
.Fa void
|
|
.Fc
|
|
.Ft void
|
|
.Fo dispatch_set_target_queue
|
|
.Fa "dispatch_object_t object"
|
|
.Fa "dispatch_queue_t target"
|
|
.Fc
|
|
.Sh DESCRIPTION
|
|
Queues are the fundamental mechanism for scheduling blocks for execution within
|
|
the
|
|
.Xr dispatch 3
|
|
framework.
|
|
.Pp
|
|
All blocks submitted to dispatch queues are dequeued in FIFO order.
|
|
Queues created with the
|
|
.Dv DISPATCH_QUEUE_SERIAL
|
|
attribute wait for the previously dequeued block to complete before dequeuing
|
|
the next block. A queue with this FIFO completion behavior is usually simply
|
|
described as a "serial queue." All memory writes performed by a block dispatched
|
|
to a serial queue are guaranteed to be visible to subsequent blocks dispatched
|
|
to the same queue. Queues are not bound to any specific thread of execution and
|
|
blocks submitted to independent queues may execute concurrently.
|
|
.Pp
|
|
Queues created with the
|
|
.Dv DISPATCH_QUEUE_CONCURRENT
|
|
attribute may execute dequeued blocks concurrently and support barrier blocks
|
|
submitted with the dispatch barrier API.
|
|
.Sh CREATION
|
|
Queues are created with the
|
|
.Fn dispatch_queue_create
|
|
function. Queues, like all dispatch objects, are reference counted and newly
|
|
created queues have a reference count of one.
|
|
.Pp
|
|
The optional
|
|
.Fa label
|
|
argument is used to describe the purpose of the queue and is useful during
|
|
debugging and performance analysis. If a label is provided, it is copied.
|
|
By convention, clients should pass a reverse DNS style label. For example:
|
|
.Pp
|
|
.Bd -literal -offset indent
|
|
my_queue = dispatch_queue_create("com.example.subsystem.taskXYZ",
|
|
DISPATCH_QUEUE_SERIAL);
|
|
.Ed
|
|
.Pp
|
|
The
|
|
.Fa attr
|
|
argument specifies the type of queue to create and must be either
|
|
.Dv DISPATCH_QUEUE_SERIAL
|
|
or
|
|
.Dv DISPATCH_QUEUE_CONCURRENT .
|
|
.Pp
|
|
The
|
|
.Fn dispatch_queue_get_label
|
|
function returns the label provided when the given
|
|
.Fa queue
|
|
was created (or an empty C string if no label was provided at creation).
|
|
Passing the constant
|
|
.Dv DISPATCH_CURRENT_QUEUE_LABEL
|
|
to
|
|
.Fn dispatch_queue_get_label
|
|
returns the label of the current queue.
|
|
.Sh SUSPENSION
|
|
Queues may be temporarily suspended and resumed with the functions
|
|
.Fn dispatch_suspend
|
|
and
|
|
.Fn dispatch_resume
|
|
respectively. Suspension is checked prior to block execution and is
|
|
.Em not
|
|
preemptive.
|
|
.Sh MAIN QUEUE
|
|
The dispatch framework provides a default serial queue for the application to
|
|
use. This queue is accessed via the
|
|
.Fn dispatch_get_main_queue
|
|
function.
|
|
.Pp
|
|
Programs must call
|
|
.Fn dispatch_main
|
|
at the end of
|
|
.Fn main
|
|
in order to process blocks submitted to the main queue. (See the
|
|
.Sx COMPATIBILITY
|
|
section for exceptions.) The
|
|
.Fn dispatch_main
|
|
function never returns.
|
|
.Sh GLOBAL CONCURRENT QUEUES
|
|
Unlike the main queue or queues allocated with
|
|
.Fn dispatch_queue_create ,
|
|
the global concurrent queues schedule blocks as soon as threads become
|
|
available (non-FIFO completion order). Four global concurrent queues are
|
|
provided, representing the following priority bands:
|
|
.Bl -bullet -compact -offset indent
|
|
.It
|
|
DISPATCH_QUEUE_PRIORITY_HIGH
|
|
.It
|
|
DISPATCH_QUEUE_PRIORITY_DEFAULT
|
|
.It
|
|
DISPATCH_QUEUE_PRIORITY_LOW
|
|
.It
|
|
DISPATCH_QUEUE_PRIORITY_BACKGROUND
|
|
.El
|
|
.Pp
|
|
The priority of a global concurrent queue controls the scheduling priority of
|
|
the threads created by the system to invoke the blocks submitted to that queue.
|
|
Global queues with lower priority will be scheduled for execution after all
|
|
global queues with higher priority have been scheduled. Additionally, items on
|
|
the background priority global queue will execute on threads with background
|
|
state as described in
|
|
.Xr setpriority 2
|
|
(i.e.\& disk I/O is throttled and the thread's scheduling priority is set to
|
|
lowest value).
|
|
.Pp
|
|
Use the
|
|
.Fn dispatch_get_global_queue
|
|
function to obtain the global queue of given priority. The
|
|
.Fa flags
|
|
argument is reserved for future use and must be zero. Passing any value other
|
|
than zero may result in a NULL return value.
|
|
.Sh TARGET QUEUE
|
|
The
|
|
.Fn dispatch_set_target_queue
|
|
function updates the target queue of the given dispatch object. The target
|
|
queue of an object is responsible for processing the object.
|
|
.Pp
|
|
The new target queue is retained by the given object before the previous target
|
|
queue is released. The new target queue setting will take effect between block
|
|
executions on the object, but not in the middle of any existing block executions
|
|
(non-preemptive).
|
|
.Pp
|
|
The default target queue of all dispatch objects created by the application is
|
|
the default priority global concurrent queue. To reset an object's target queue
|
|
to the default, pass the
|
|
.Dv DISPATCH_TARGET_QUEUE_DEFAULT
|
|
constant to
|
|
.Fn dispatch_set_target_queue .
|
|
.Pp
|
|
The priority of a dispatch queue is inherited from its target queue.
|
|
In order to change the priority of a queue created with
|
|
.Fn dispatch_queue_create ,
|
|
use the
|
|
.Fn dispatch_get_global_queue
|
|
function to obtain a target queue of the desired priority.
|
|
.Pp
|
|
Blocks submitted to a serial queue whose target queue is another serial queue
|
|
will not be invoked concurrently with blocks submitted to the target queue or
|
|
to any other queue with that same target queue.
|
|
.Pp
|
|
The target queue of a dispatch source specifies where its event handler and
|
|
cancellation handler blocks will be submitted. See
|
|
.Xr dispatch_source_create 3
|
|
for more information about dispatch sources.
|
|
.Pp
|
|
The target queue of a dispatch I/O channel specifies the priority of the global
|
|
queue where its I/O operations are executed. See
|
|
.Xr dispatch_io_create 3
|
|
for more information about dispatch I/O channels.
|
|
.Pp
|
|
For all other dispatch object types, the only function of the target queue is
|
|
to determine where an object's finalizer function is invoked.
|
|
.Pp
|
|
The result of passing the main queue or a global concurrent queue as the first
|
|
argument of
|
|
.Fn dispatch_set_target_queue
|
|
is undefined.
|
|
.Pp
|
|
Directly or indirectly setting the target queue of a dispatch queue to itself is
|
|
undefined.
|
|
.Sh DEPRECATED FUNCTIONS
|
|
The following functions are deprecated and will be removed in a future release:
|
|
.Bl -item
|
|
.It
|
|
.Ft dispatch_queue_t
|
|
.Fn dispatch_get_current_queue void ;
|
|
.El
|
|
.Pp
|
|
.Fn dispatch_get_current_queue
|
|
always returns a valid queue. When called from within a block
|
|
submitted to a dispatch queue, that queue will be returned. If this function is
|
|
called from the main thread before
|
|
.Fn dispatch_main
|
|
is called, then the result of
|
|
.Fn dispatch_get_main_queue
|
|
is returned. In all other cases, the default target queue will be returned.
|
|
.Pp
|
|
The use of
|
|
.Fn dispatch_get_current_queue
|
|
is strongly discouraged except for debugging and logging purposes. Code must not
|
|
make any assumptions about the queue returned, unless it is one of the global
|
|
queues or a queue the code has itself created. The returned queue may have
|
|
arbitrary policies that may surprise code that tries to schedule work with the
|
|
queue. The list of policies includes, but is not limited to, queue width (i.e.
|
|
serial vs. concurrent), scheduling priority, security credential or filesystem
|
|
configuration. This function is deprecated and will be removed in a future
|
|
release.
|
|
.Pp
|
|
It is equally unsafe for code to assume that synchronous execution onto a queue
|
|
is safe from deadlock if that queue is not the one returned by
|
|
.Fn dispatch_get_current_queue .
|
|
.Pp
|
|
The result of
|
|
.Fn dispatch_get_main_queue
|
|
may or may not equal the result of
|
|
.Fn dispatch_get_current_queue
|
|
when called on the main thread. Comparing the two is not a valid way to test
|
|
whether code is executing on the main thread. Foundation/AppKit programs should
|
|
use [NSThread isMainThread]. POSIX programs may use
|
|
.Xr pthread_main_np 3 .
|
|
.Pp
|
|
.Fn dispatch_get_current_queue
|
|
may return a queue owned by a different subsystem which has already had all
|
|
external references to it released. While such a queue will continue to exist
|
|
until all blocks submitted to it have completed, attempting to retain it is
|
|
forbidden and will trigger an assertion. If Objective-C Automatic Reference
|
|
Counting is enabled, any use of the object returned by
|
|
.Fn dispatch_get_current_queue
|
|
will cause retain calls to be automatically generated, so the use of
|
|
.Fn dispatch_get_current_queue
|
|
for any reason in code built with ARC is particularly strongly discouraged.
|
|
.Sh COMPATIBILITY
|
|
Cocoa applications need not call
|
|
.Fn dispatch_main .
|
|
Blocks submitted to the main queue will be executed as part of the "common
|
|
modes" of the application's main NSRunLoop or CFRunLoop.
|
|
However, blocks submitted to the main queue in applications using
|
|
.Fn dispatch_main
|
|
are not guaranteed to execute on the main thread.
|
|
.Pp
|
|
The dispatch framework is a pure C level API. As a result, it does not catch
|
|
exceptions generated by higher level languages such as Objective-C or C++.
|
|
Applications
|
|
.Em MUST
|
|
catch all exceptions before returning from a block submitted to a dispatch
|
|
queue; otherwise the process will be terminated with an uncaught exception.
|
|
.Pp
|
|
The dispatch framework manages the relationship between dispatch queues and
|
|
threads of execution. As a result, applications
|
|
.Em MUST NOT
|
|
delete or mutate objects that they did not create. The following interfaces
|
|
.Em MUST NOT
|
|
be called by blocks submitted to a dispatch queue:
|
|
.Bl -bullet -offset indent
|
|
.It
|
|
.Fn pthread_cancel
|
|
.It
|
|
.Fn pthread_detach
|
|
.It
|
|
.Fn pthread_join
|
|
.It
|
|
.Fn pthread_kill
|
|
.It
|
|
.Fn pthread_exit
|
|
.El
|
|
.Pp
|
|
Applications
|
|
.Em MAY
|
|
call the following interfaces from a block submitted to a dispatch queue if
|
|
and only if they restore the thread to its original state before returning:
|
|
.Bl -bullet -offset indent
|
|
.It
|
|
.Fn pthread_setcancelstate
|
|
.It
|
|
.Fn pthread_setcanceltype
|
|
.It
|
|
.Fn pthread_setschedparam
|
|
.It
|
|
.Fn pthread_sigmask
|
|
.It
|
|
.Fn pthread_setugid_np
|
|
.El
|
|
.Pp
|
|
Applications
|
|
.Em MUST NOT
|
|
rely on the following interfaces returning predictable results between
|
|
invocations of blocks submitted to a dispatch queue:
|
|
.Bl -bullet -offset indent
|
|
.It
|
|
.Fn pthread_self
|
|
.It
|
|
.Fn pthread_getschedparam
|
|
.It
|
|
.Fn pthread_get_stacksize_np
|
|
.It
|
|
.Fn pthread_get_stackaddr_np
|
|
.It
|
|
.Fn pthread_mach_thread_np
|
|
.It
|
|
.Fn pthread_from_mach_thread_np
|
|
.El
|
|
.Pp
|
|
While the result of
|
|
.Fn pthread_self
|
|
may change between invocations of blocks, the value will not change during the
|
|
execution of any single block. Because the underlying thread may change beteween
|
|
block invocations on a single queue, using per-thread data as an out-of-band
|
|
return value is error prone. In other words, the result of calling
|
|
.Fn pthread_setspecific
|
|
and
|
|
.Fn pthread_getspecific
|
|
is well defined within a signle block, but not across multiple blocks. Also,
|
|
one cannot make any assumptions about when the destructor passed to
|
|
.Fn pthread_key_create
|
|
is called. The destructor may be called between the invocation of blocks on
|
|
the same queue, or during the idle state of a process.
|
|
.Pp
|
|
The following example code correctly handles per-thread return values:
|
|
.Bd -literal -offset indent
|
|
__block int r;
|
|
__block int e;
|
|
dispatch_sync(queue, ^{
|
|
r = kill(1, 0);
|
|
// Copy the per-thread return value to the callee thread
|
|
e = errno;
|
|
});
|
|
printf("kill(1,0) returned %d and errno %d\n", r, e);
|
|
.Ed
|
|
.Pp
|
|
Note that in the above example
|
|
.Va errno
|
|
is a per-thread variable and must be copied out explicitly as the block may be
|
|
invoked on different thread of execution than the caller. Another example of
|
|
per-thread data that would need to be copied is the use of
|
|
.Fn getpwnam
|
|
instead of
|
|
.Fn getpwnam_r .
|
|
.Pp
|
|
As an optimization,
|
|
.Fn dispatch_sync
|
|
invokes the block on the current thread when possible. In this case, the thread
|
|
specific data such as
|
|
.Va errno
|
|
may persist from the block until back to the caller. Great care should be taken
|
|
not to accidentally rely on this side-effect.
|
|
.Pp
|
|
.Sh SEE ALSO
|
|
.Xr dispatch 3 ,
|
|
.Xr dispatch_async 3 ,
|
|
.Xr dispatch_object 3 ,
|
|
.Xr dispatch_source_create 3
|