Some points of study on multi-thread GCD

Source: Internet
Author: User
Tags gcd semaphore

GCD is the most convenient use of multi-threaded, but also use more.

Learning GCD mainly focus on the following points:

One, queue, synchronous, asynchronous

1. Home row: Dispatch_get_main_queue ();

2. Serial queue: dispatch_queue_create ("queue", 0);

3. Parallel queue: Dispatch_get_global_queue (dispatch_queue_priority_default, 0);

4. Synchronous, asynchronous there is no need to say anything more.

Some explanations of the above keywords:

Primary queue: The primary queue can only use asynchronous to perform tasks in the queue, and using synchronization can cause a dead loop. Execution of the task at the same time is performed in the main thread.

Serial queue: (1), the task added to the serial queue is executed one after the other, that is, the next task is not started until the last task is executed;

However, multiple serial queues can be created, and each serial queue is independent from one another and can be executed concurrently.

(2), if synchronous execution is performed on the current thread;

(3), if executed asynchronously is a new thread execution.

Parallel queues: (1), tasks added to the parallel queue can be started concurrently, the boot order is still one after the other, but the latter can begin execution without waiting for the former to execute.

Parallel queues can also be created with multiple, independent and concurrent execution of each other.

(2), if synchronous execution is performed on the current thread;

(3), if executed asynchronously is a new thread execution.

Second, often used in the place

1. Perform some operations after the task is completed

2. Execute only once

3. Delay operation

Some explanations for the above uses:

(1), the task after the completion of a number of operations, if it is some simple operation can be directly used in serial queue implementation. But some of the more time-consuming operations need to use queue groups.

1. Create a queue group
dispatch_group_t group = Dispatch_group_create ();

2. Start a Task 1
Dispatch_group_async (Group, Global_quque, ^{

});

3. Start a Task 2
Dispatch_group_async (Group, Global_quque, ^{


});

4. All the tasks in the group are completed, then go back to the main thread to perform other operations
Dispatch_group_notify (Group,main_queue, ^{
    });
 

(2), execute only once

Static dispatch_once_t Oncetoken;

Dispatch_once (&oncetoken, ^{

Execute code only 1 times (this is thread-safe by default)

});

(3), delay operation

Dispatch_after (Dispatch_time (Dispatch_time_now, (int64_t) (5.0 * nsec_per_sec)), Dispatch_get_main_queue (), ^{

Methods for deferred execution

});

(4), pausing and resuming tasks in the queue

Dispatch_suspend and Dispatch_resume

We know that Nsoperationqueue has a pause (suspend) and recovery (resume). In fact, the queue in GCD also has a similar function. The usage is also very simple:

Dispatch_suspend (queue) //Pause a queue

Dispatch_resume (queue) //Restore a queue

These functions do not affect tasks that have already been performed in the queue, and after a queue has been paused, tasks that have been added to the queue but not yet executed will not be executed until the queue is resumed.

(5), connecting link

Dispatch_async (queue, block1_for_reading)

Dispatch_async (queue, block2_for_reading)

Dispatch_barrier_async (queue, block_for_writing)

Dispatch_async (queue, block3_for_reading)

Dispatch_async (queue, block4_for_reading)

Dispatch_barrier_async will divide the running cycle of the parallel queue into these three processes:

    1. First, wait until all tasks in the parallel queue are currently executed.
    2. Begins the execution of a task in Dispatch_barrier_async, which does not execute even if a task is submitted to a parallel queue
    3. The parallel queue returns to normal after the task execution in Dispatch_barrier_async has completed.

In general,Dispatch_barrier_async played a " connecting link" role. It ensures that previous tasks are performed on their own before the task is executed later. As the meaning of barrier, it acts as a fence, or as a watershed.

This allows for efficient data and file reading and writing using parallel queues and Dispatc_barrier_async methods.

(6), signal volume

Dispatch_semaphore

First, the concept of the semaphore (semaphore) is introduced. The semaphore is the signal to hold the count, but the explanation is no explanation. Let's take a look at the example of life.

Suppose there is a house, which corresponds to the concept of a process, the person in the house corresponds to the thread. A process can include multiple threads. The house (process) has a lot of resources, such as garden, living room, etc., which are shared by all people (threads).

But in some places, such as the bedroom, up to two people can go to sleep. What to do, put two keys on the bedroom door. The person who goes in (the thread) takes the key in, can't go in without the key, and puts the key back at the door when it comes out.

At this time, the number of keys at the door is called the Semaphore (Semaphore). Obviously, a semaphore of 0 waits, the semaphore is not zero, minus 1 and does not wait.

In GCD, the syntax for creating semaphores is as follows:

var semaphore = dispatch_semaphore_create (2)

This code creates a semaphore with the Dispatch_semaphore_create method and sets the initial value to 2. You can then call the Dispatch_semaphore_wait method.

Dispatch_semaphore_wait (semaphore, Dispatch_time_forever)

The dispatch_semaphore_wait method means to wait until the value of the semaphore is greater than or equal to 1, and when this method executes, the value of the first semaphore parameter is reduced by 1.

The second parameter is a dispatch_time_t type of time, which represents the maximum wait time for this method. This has been said in the first chapter, for example, dispatch_time_forever means to wait forever.

The return value is also the same as the dispatch_group_wait method, which returns 0 indicating that the value of the first parameter semaphore is greater than or equal to 1 within the specified wait time, otherwise the specified wait time is exceeded, but the semaphore value is 0.

The dispatch_semaphore_wait method returns 0 because the value of the semaphore at this time is greater than or equal to one, and the task obtains the permissions that can be performed. At this point we can safely perform tasks that require exclusive control.

You also need to call the Dispatch_semaphore_signal () method at the end of the task to add a semaphore value of 1. This is similar to what was said before, from the bedroom to put the lock on the door, or later people will not be able to enter.

Let's look at a complete example:

var semaphore = dispatch_semaphore_create (1)

Let queue = dispatch_queue_create ("Com.gcd.kt", dispatch_queue_concurrent)

var array: [INT] = []

For i in 1... 100000 {

Dispatch_async (queue, {()-Void in

 /*

A thread executes here, and if the semaphore value is 1, then the Wait method returns 1, starting with the next operation.

At the same time, because the signal is 0, other threads executing here must wait

*/

Dispatch_semaphore_wait (semaphore, Dispatch_time_forever)

 /*

After the wait method has been executed, the value of the semaphore becomes 0. You can do the following.

At this point other threads have to wait for the wait method to return.

The thread that can be modified on the array has only one at any time and can safely modify the array

*/

Array.append (i)

 /*

When the exclusive operation is finished, remember to call the signal method and add 1 to the semaphore value.

This way, if another thread waits for the wait function to return, it is executed by the first waiting thread.

*/

Dispatch_semaphore_signal (semaphore)

})

}

Summarize:

1, the commonly used delay operation:

(1) Dispatch_after (Dispatch_time (Dispatch_time_now, (int64_t) (5.0 * nsec_per_sec)), Dispatch_get_main_queue (), ^{

Methods for deferred execution

});

(2) [Self performselector: @selector (Test) Withobject:nil afterdelay:1.0];

2, back to the main thread operation:

(1) Dispatch_async (Dispatch_get_main_queue (), ^{

Back to the main thread, hold? UI Refresh Action});

(2) [Self.imageview performselectoronmainthread: @selector (setimage:) withobject:image Waituntildone:no];

Some points of study on multi-thread 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.