Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
dispatch_queue_create(3) BSD Library Functions Manual dispatch_queue_create(3)

     dispatch_queue_create, dispatch_queue_get_label,
     dispatch_get_current_queue, dispatch_get_global_queue,
     dispatch_get_main_queue, dispatch_main, dispatch_set_target_queue --
     where blocks are scheduled	for execution

     #include <dispatch/dispatch.h>

     dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);

     const char	*
     dispatch_queue_get_label(dispatch_queue_t queue);


     dispatch_get_global_queue(long priority, unsigned long flags);



     dispatch_set_target_queue(dispatch_object_t object,
	 dispatch_queue_t target);

     Queues are	the fundamental	mechanism for scheduling blocks	for execution
     within the	dispatch(3) framework.

     All blocks	submitted to dispatch queues are dequeued in FIFO order.  By
     default, queues created with dispatch_queue_create() wait for the previ-
     ously dequeued block to complete before dequeuing the next	block. This
     FIFO completion behavior is sometimes simply described as a "serial
     queue."  Queues are not bound to any specific thread of execution and
     blocks submitted to independent queues may	execute	concurrently.  Queues,
     like all dispatch objects,	are reference counted and newly	created	queues
     have a reference count of one.

     The optional label	argument is used to describe the purpose of the	queue
     and is useful during debugging and	performance analysis. By convention,
     clients should pass a reverse DNS style label.  If	a label	is provided,
     it	is copied. If a	label is not provided, then dispatch_queue_get_label()
     returns an	empty C	string.	 For example:

     my_queue =	dispatch_queue_create("com.example.subsystem.taskXYZ", NULL);

     The attr argument is reserved for future use and must be NULL.

     Queues may	be temporarily suspended and resumed with the functions
     dispatch_suspend()	and dispatch_resume() respectively. Suspension is
     checked prior to block execution and is not preemptive.

     The dispatch framework provides a default serial queue for	the applica-
     tion to use.  This	queue is accessed via dispatch_get_main_queue().  Pro-
     grams must	call dispatch_main() at	the end	of main() in order to process
     blocks submitted to the main queue. (See the compatibility	section	for

     Unlike the	main queue or queues allocated with dispatch_queue_create(),
     the global	concurrent queues schedule blocks as soon as threads become
     available (non-FIFO completion order). The	global concurrent queues rep-
     resent three priority bands:

     Blocks submitted to the high priority global queue	will be	invoked	before
     those submitted to	the default or low priority global queues. Blocks sub-
     mitted to the low priority	global queue will only be invoked if no	blocks
     are pending on the	default	or high	priority queues.

     The dispatch_queue_create() function returns NULL on failure.

     The dispatch_queue_get_label() function always returns a valid C string.
     An	empty C	string is returned if the label	was NULL creation time.

     The dispatch_get_main_queue() function returns the	default	main queue.

     The dispatch_get_current_queue() function 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
     dispatch_main() is	called,	then the result	of dispatch_get_main_queue()
     is	returned.  Otherwise, the result of
     dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,	0) will	be re-
     turned in all other cases.

     The dispatch_main() function never	returns.

     The 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. Currently only dispatch queues and dispatch
     sources are supported by this function. The result	of using
     dispatch_set_target_queue() with any other	dispatch object	type is	unde-

     The new target queue is retained by the given object before the previous
     target queue is released. The new target queue will take effect between
     block executions, but not in the middle of	any existing block executions

     The priority of a dispatch	queue is inherited by its target queue.	 In
     order to change the priority of a queue created with
     dispatch_queue_create(), use the dispatch_get_global_queue() function to
     obtain a target queue of the desired priority. The	flags argument is re-
     served for	future use and must be zero. Passing any value other than zero
     may result	in a NULL return value.

     The target	queue of a dispatch source specifies where its event handler
     and cancellation handler blocks will be submitted.	See
     dispatch_source_create(3) for more	information about dispatch sources.

     The result	of passing the main queue or a global concurrent queue to the
     first argument of dispatch_set_target_queue() is undefined.

     Directly or indirectly setting the	target queue of	a dispatch queue to
     itself is undefined.

     Code cannot make any assumptions about the	queue returned by
     dispatch_get_current_queue().  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. Therefore, dispatch_get_current_queue() MUST
     only be used for identity tests or	debugging.

     Cocoa applications	need not call dispatch_main().	Blocks submitted to
     the main queue will be executed as	part of	the "common modes" of the ap-
     plication's main NSRunLoop	or CFRunLoop.  However,	blocks submitted to
     the main queue in applications using dispatch_main() are not guaranteed
     to	execute	on the main thread.

     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 MUST	catch all exceptions before returning from a
     block submitted to	a dispatch queue; otherwise the	internal data struc-
     tures of the dispatch framework will be left in an	inconsistent state.

     The dispatch framework manages the	relationship between dispatch queues
     and threads of execution. As a result, applications MUST NOT delete or
     mutate objects that they did not create. The following interfaces MUST
     NOT be called by blocks submitted to a dispatch queue:

	   +o   pthread_cancel()

	   +o   pthread_detach()

	   +o   pthread_join()

	   +o   pthread_kill()

	   +o   pthread_exit()

     Applications 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:

	   +o   pthread_setcancelstate()

	   +o   pthread_setcanceltype()

	   +o   pthread_setschedparam()

	   +o   pthread_sigmask()

	   +o   pthread_setugid_np()

	   +o   pthread_chdir()

	   +o   pthread_fchdir()

     Applications MUST NOT rely	on the following interfaces returning predict-
     able results between invocations of blocks	submitted to a dispatch	queue:

	   +o   pthread_self()

	   +o   pthread_getschedparam()

	   +o   pthread_get_stacksize_np()

	   +o   pthread_get_stackaddr_np()

	   +o   pthread_mach_thread_np()

	   +o   pthread_from_mach_thread_np()

     While the result of 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 invoca-
     tions 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
     pthread_setspecific() and 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 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.

     The following example code	correctly handles per-thread return values:

	   __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 %d0,	r, e);

     Note that in the above example 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 getpwnam()	instead	of getpwnam_r().

     As	an optimization, dispatch_sync() invokes the block on the current
     thread when possible. In this case, the thread specific data such as
     errno may persist from the	block until back to the	caller.	Great care
     should be taken not to accidentally rely on this side-effect.

     dispatch(3), dispatch_async(3), dispatch_object(3),

Darwin				  May 1, 2008				Darwin


Want to link to this manual page? Use this URL:

home | help