The core of GCD programming is the dispatch queue. The execution of the dispatch block will eventually be put into a certain queue for execution. It is similar to NSOperationQueue but is more complex and powerful, and can be used in nesting. Therefore, combined with the GCD implemented by block, the features of function closures are fully utilized.
There are several ways to generate dispatch queues:
1. dispatch_queue_t queue = dispatch_queue_create("", DISPATCH_QUEUE_SERIAL); // Generate a serial queue, and the blocks in the queue are executed in the order of first-in-first-out (FIFO), which is actually executed by a single thread. The first parameter is the name of the queue, which will be very useful when debugging the program. Try not to rename all names.
2. dispatch_queue_t queue = dispatch_queue_create("", DISPATCH_QUEUE_CONCURRENT); // Generate a concurrent execution queue, and the block is distributed to multiple threads for execution
3. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // Obtain the concurrent queue generated by the program process by default. You can set priority to select the three priority queues of high, medium and low. Since it is generated by the system by default, dispatch_resume() and dispatch_suspend() cannot be called to control execution continuation or interruption. It should be noted that three queues do not represent three threads, and there may be more threads. The concurrent queue can automatically generate a reasonable number of threads according to the actual situation, and it can also be understood as the dispatch queue implements the management of a thread pool and is transparent to the program logic.
The official website document explains that there are three concurrent queues in total, but there is actually a lower priority queue, setting the priority to DISPATCH_QUEUE_PRIORITY_BACKGROUND. During Xcode debugging, you can observe the various dispatch queues that are being used.
4. dispatch_queue_t queue = dispatch_get_main_queue(); //Get the dispatch queue of the main thread, which is actually a serial queue. The execution of the main thread dispatch queue is also uncontrollable or interrupted.
Thread operation example
In order to facilitate the use of GCD, Apple provides some methods to facilitate our block execution in the main thread or background thread, or delay execution. Examples of use are as follows:
// Backend execution:
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// something
});
// Main thread execution:
dispatch_async(dispatch_get_main_queue(), ^{
// something
});
// Execute at one time:
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// code to be executed once
});
// Delay to execute 2 seconds:
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
// code to be executed on the main queue after delay
});
dispatch_queue_t can also be defined by yourself. If you want to customize queue, you can use dispatch_queue_create method. The example is as follows:
// Custom dispatch_queue_t
dispatch_queue_t urls_queue = dispatch_queue_create("", NULL);
dispatch_async(urls_queue, ^{
// your code
});
dispatch_release(urls_queue);
In addition, GCD has some advanced usages, such as allowing two threads in the background to execute in parallel, and then summarizing the execution results after both threads are finished. This can be implemented using dispatch_group_t, dispatch_group_async, dispatch_group_notify. The example is as follows:
// Merge summary results
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
// Thread execution in parallel
});
dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
// Thread 2 that executes in parallel
});
dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{
// Summary of results
});
The dispatch queue does not support cancel (cancel), and does not implement the dispatch_cancel() function. Unlike NSOperationQueue, I have to say that this is a small flaw.