Dispatch Queues GCD

Source: Internet
Author: User

We can almost dispatch the queue to complete all the tasks that are done with threads. Scheduling queues are simpler, easier to use, and more efficient than thread code.

The following is a summary of the scheduling queue, how to use the scheduling queue in the application to perform tasks.


1. About scheduling queues

All dispatch queues are FIFO queues, so the order in which the tasks in the queue starts is the same as the order in which they are added to the queue. GCD automatically provides us with some scheduling queues, and we can also create new ones for specific purposes.

The following lists the types of scheduling queues available and how to use them.

(1) Serial Queues (serial queue), also known as the private dispatch queue, is generally used for synchronous access to specific resources. We can create as many serial queues as we need, and each serial queue is concurrent.

(2) Parallel queue, also known as global dispatch queue. While parallel queues can perform multiple tasks concurrently, the order in which the tasks start executing is the same as the order in which they join the queue. We can't do this ourselves. Create a parallel dispatch queue. There are only three available global concurrent queues.

Dispatch Queues

Dispatch queues from the point of use will be more like another form of operation queues just operation queues is the Dispatch queues with Object C is C's

Dispatch Queues has serial Queues also known as Private dispatch Queues, a time can only run one task, run sequentially

dispatch_queue_t queue;

Queue = Dispatch_queue_create ("Myqueue", NULL);

Dispatch_async (Queue, ^{

printf ("Do some work here.\n");

});

printf ("The first block may or could not be run.\n");

Dispatch_sync (Queue, ^{

printf ("Do some more work here.\n");

});

printf ("Both blocks has completed.\n");

With synchronous dispatch and asynchronous dispatch, it is recommended to use Dispatch_async in order to truly embody the advantages of synchronization equivalent to Waituntildone = YES

Another is the concurrent Queues each program system automatically provides 3 concurrent Queues

dispatch_queue_t Aqueue = dispatch_get_global_queue (dispatch_queue_priority_default, 0);

dispatch_queue_t ahqueue = dispatch_get_global_queue (dispatch_queue_priority_high, 0);

dispatch_queue_t alqueue = dispatch_get_global_queue (dispatch_queue_priority_low, 0);

What does it mean to see that 3 priority concurrent queues

The last special dispatch queue is the main dispatch queue, which is also the program startup auto-generation

dispatch_queue_t mainqueue = Dispatch_get_main_queue ();

Concurrent queues and main queue are generated by the system and Dispatch_suspend, Dispatch_resume, Dispatch_set_context, these functions are invalid for them


(3) The main dispatch queue is a globally available serial queue that performs tasks on the main thread of the program. This queue's tasks are alternately executed with the event source that the application's main loop (run loop) is to execute. Because it runs in the main thread of the application, the main queue is often used as a synchronization point for the application.


2. Some techniques for queuing

In addition to scheduling queues, GCD also provides some useful techniques to help us manage our code.

Dispath Group, dispatch semaphore, Dispath sources


3. Use blocks to accomplish tasks

Block objects is based on the C language feature and can be used in c,c++ objective-c. A block, although somewhat similar to a function pointer, actually represents a lower-level data structure, similar to an object, with compilers to create and manage.

One advantage of block is that it can use variables of its own extraterritorial scope, for example, a block can read the variable value of its parent scope, which is copied into the data structure of the block heap. When a block is added to the dispatch queue, these values are usually read-only.

The declaration of the block is similar to the function pointer, except that the * is changed to ^, and we can pass the parameter to block or receive the value it returns.


4. Create and manage scheduling queues

(1) Obtain global concurrency dispatch queue (global concurrent Dispath queues)

The system provides three concurrent dispatch queues for each application. These three concurrent dispatch queues are global, and they differ only by priority. Because it's global, we don't need to create it. We only need to get the queue by using the function Dispath_get_global_queue, as follows:

dispatch_queue_t Aqueue = dispatch_get_global_queue (dispatch_queue_priority_default, 0);

In addition to getting the default concurrency queue, you can also pass parameters Dispatch_queue_priopity_high and Dispatch_queue_priopity_low to get high or low priority. (the second parameter is reserved for future expansions)

Although the dispatch queue is a reference counting object, this is because the queue is global and does not require us to go to retain or release, we need to call the function Dispath_get_global_queue directly when we use it.


(2) Creating a serial dispatch queue

Serial queues are useful when you want tasks to execute in a particular order. A serial queue performs only one task at a time. We can use serial queues instead of locks to protect shared data. Unlike locks, a serial queue guarantees that the task executes in a predictable order.

Unlike concurrent queues, we create and manage serial queues on our own, and can create any number of serial queues. When we create a serial queue, it should be for some purpose, such as securing resources, or synchronizing certain key behaviors of the application.

The following code describes how to create a custom serial queue, the function dispath_queue_create requires two parameters, the queue's name, and the queue's properties. Debugger and performance tools display the name of the queue help us to track how the task executes, the properties of the queue are reserved for future use, should be null

dispatch_queue_t queue;

Queue = Dispatch_queue_create ("Com.example.MyQueue", NULL);

In addition to the custom queues that you create, the system automatically creates a serial queue for me and binds it to the main thread of the application. Here's how to get it.


(3) Run-time access to common queues

GCD provides a number of functions that allow us to easily access the common dispatch queues

Use the Dispatch_get_current_queue function to debug or test to get the identity of the current queue.

Use the function Dispatch_get_main_queue to get a serial dispatch queue that is connected to the main thread of the application.


(4) Memory management of scheduling queue

The dispatch queue is a reference count type, and we want to release it when we create a serial dispatch queue. You can use the function Dispatch_retain and dispatch_release to increase or decrease the reference count.


(5) Store custom context information in one queue

All scheduling objects allow us to associate them with a custom context data, which is used by functions Dispatch_set_context and Dispatch_get_context, and the system does not use our custom data, and we allocate and release it at the right time.


For queues, context data is typically used to store a pointer to an object, or other data structure, and we can release the context in the queue's finalizer function. An example is given below.


(6) Provide a clean up function for the queue.

After we have created the serial dispatch queue, we can connect it to a finalizer function to clean up the data that needs to be cleaned up in the queue. We can use the Dispatch_set_finalizer_f function to set a function that will be called automatically when the reference count of the queue is 0. Use this function to clean up the context data associated with the queue, which is called when the context pointer is not NULL.

Shows a custom finalizer function and a function that creates a queue and installs that finalizer. The queue uses the finalizer function to release the data stored in the queue ' s context pointer. (The myinitializedatacontextfunction and mycleanupdatacontextfunction functions referenced from the code is custom funct Ions the would provide to initialize and the contents of the data structure itself.) The context pointer passed to the FINALIZER function contains the data object associated with the queue.

void myfinalizerfunction (void *context)

{

mydatacontext* thedata = (mydatacontext*) context;

Clean up the contents of the structure

Mycleanupdatacontextfunction (Thedata);

Now release the structure itself.

Free (thedata);

}

dispatch_queue_t Createmyqueue ()

{

mydatacontext* data = (mydatacontext*) malloc (sizeof (Mydatacontext));

Myinitializedatacontextfunction (data);

Create the queue and set the context data.

dispatch_queue_t serialqueue = dispatch_queue_create ("Com.example.CriticalTaskQueue", NULL);

if (serialqueue)

{

Dispatch_set_context (serialqueue, data);

Dispatch_set_finalizer_f (Serialqueue, &myfinalizerfunction);

}

return serialqueue;

}


5. Add a task to the queue

(1)

There are two ways to add a task to a queue, either synchronously or asynchronously. Use Dispatch_async and Dispatch_async_f functions as much as possible to perform, rather than synchronizing the preferred. When we add a block object or function to the queue, we have no way to know when the code executes.

Using this async does not block the main thread.

Although it is possible to add tasks asynchronously, in some cases synchronizing the way to add a task will prevent some synchronization errors. The functions Dispatch_sync and dispatch_sync_f are called in a synchronous manner. This function blocks the execution of the main thread until the specified task finishes.

Here is the code example:

dispatch_queue_t Mycustomqueue;

Mycustomqueue = Dispatch_queue_create ("Com.example.MyCustomQueue", NULL);

Dispatch_async (Mycustomqueue, ^{

printf ("Do some work here.\n");

});

printf ("The first block may or could not be run.\n");

Dispatch_sync (Mycustomqueue, ^{

printf ("Do some more work here.\n");

});

printf ("Both blocks has completed.\n");


(2) Execute completion block when the task is completed

When the task is completed, our application needs to be notified, once again to merge the results, in traditional asynchronous programming, we may use the callback function, but in the dispatch queue, we use completion block.

void Average_async (int *data, size_t len,

dispatch_queue_t queue, void (^block) (int))

{

Retain the queue provided by the user to make

Sure it does not disappear before the completion

Block can be called.

Dispatch_retain (queue);

Do the work in the default concurrent queue and then

Call the user-provided block with the results.

Dispatch_async (Dispatch_get_global_queue (dispatch_queue_priority_default, 0), ^{

int avg = AVERAGE (data, Len);

Dispatch_async (Queue, ^{block (avg);});

Release the user-provided queue when done

Dispatch_release (queue);

});

}

(3) Concurrent Execution loop iteration (loop iterations)

For a For loop, if each iteration has no effect on each other, you can execute the iteration concurrently, using the function dispatch_apply or the Dispatch_apply_f function.

As with normal loops, functions dispatch_apply or dispatch_apply_f are not returned until all loop iterations are complete.

The following code:

dispatch_queue_t queue = Dispatch_get_global_queue (Dispatch_queue_priority_default, 0);

Dispatch_apply (count, queue, ^ (size_t i) {

printf ("%u\n", I);

});

(4) Perform the task on the main thread

We can get to the main thread's dispatch queue by calling the function Dispatch_get_main_queue.


Dispatch Queues GCD

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.