Replacing Threads with Dispatch Queues

To understand how you might replace threads with dispatch queues, first consider some of the ways you might be using threads in your application today:

  • Single task threads. Create a thread to perform a single task and release the thread when the task is done.

  • Worker threads. Create one or more worker threads with specific tasks in mind for each. Dispatch tasks to each thread periodically.

  • Thread pools. Create a pool of generic threads and set up run loops for each one. When you have a task to perform, grab a thread from the pool and dispatch the task to it. If there are no free threads, queue the task and wait for a thread to become available.

Although these might seem like dramatically different techniques, they are really just variants on the same principle. In each case, a thread is being used to run some task that the application has to perform. The only difference between them is the code used to manage the threads and the queueing of tasks. With dispatch queues and operation queues, you can eliminate all of your thread and thread-communication code and instead focus on just the tasks you want to perform.

If you are using one of the above threading models, you should already have a pretty good idea of the type of tasks your application performs. Instead of submitting a task to one of your custom threads, try encapsulating that task in an operation object or a block object and dispatching it to the appropriate queue. For tasks that are not particularly contentious—that is, tasks that do not take locks—you should be able to make the following direct replacements:

  • For a single task thread, encapsulate the task in a block or operation object and submit it to a concurrent queue.

  • For worker threads, you need to decide whether to use a serial queue or a concurrent queue. If you use worker threads to synchronize the execution of specific sets of tasks, use a serial queue. If you do use worker threads to execute arbitrary tasks with no interdependencies, use a concurrent queue.

  • For thread pools, encapsulate your tasks in a block or operation object and dispatch them to a concurrent queue for execution.

Of course, simple replacements like this may not work in all cases. If the tasks you are executing contend for shared resources, the ideal solution is to try to remove or minimize that contention first. If there are ways that you can refactor or rearchitect your code to eliminate mutual dependencies on shared resources, that is certainly preferable. However, if doing so is not possible or might be less efficient, there are still ways to take advantage of queues. A big advantage of queues is that they offer a more predictable way to execute your code. This predictability means that there are still ways to synchronize the execution of your code without using locks or other heavyweight synchronization mechanisms. Instead of using locks, you can use queues to perform many of the same tasks:

  • If you have tasks that must execute in a specific order, submit them to a serial dispatch queue. If you prefer to use operation queues, use operation object dependencies to ensure that those objects execute in a specific order.

  • If you are currently using locks to protect a shared resource, create a serial queue to execute any tasks that modify that resource. The serial queue then replaces your existing locks as the synchronization mechanism. For more information techniques for getting rid of locks, see Eliminating Lock-Based Code.

  • If you use thread joins to wait for background tasks to complete, consider using dispatch groups instead. You can also use an  NSBlockOperation object or operation object dependencies to achieve similar group-completion behaviors. For more information on how to track groups of executing tasks, see Replacing Thread Joins.

  • If you use a producer-consumer algorithm to manage a pool of finite resources, consider changing your implementation to the one shown in Changing Producer-Consumer Implementations.

  • If you are using threads to read and write from descriptors, or monitor file operations, use the dispatch sources as described in Dispatch Sources.

It is important to remember that queues are not a panacea for replacing threads. The asynchronous programming model offered by queues is appropriate in situations where latency is not an issue. Even though queues offer ways to configure the execution priority of tasks in the queue, higher execution priorities do not guarantee the execution of tasks at specific times. Therefore, threads are still a more appropriate choice in cases where you need minimal latency, such as in audio and video playback.

https://developer.apple.com/library/content/documentation/General/Conceptual/ConcurrencyProgrammingGuide/ThreadMigration/ThreadMigration.html#//apple_ref/doc/uid/TP40008091-CH105-SW10

Replacing Threads with Dispatch Queues的更多相关文章

  1. Dispatch Queues and Thread Safety

    Dispatch Queues and Thread Safety It might seem odd to talk about thread safety in the context of di ...

  2. iOS 并行编程:GCD Dispatch Queues

    1 简介 1.1 功能          Grand Central Dispatch(GCD)技术让任务并行排队执行,根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务.任务可以是一个函数 ...

  3. Dispatch Queues 线程池

    Dispatch Queues Dispatch queues are a C-based mechanism for executing custom tasks. A dispatch queue ...

  4. Multithreading annd Grand Central Dispatch on ios for Beginners Tutorial-多线程和GCD的入门教程

    原文链接:Multithreading and Grand Central Dispatch on iOS for Beginners Tutorial Have you ever written a ...

  5. Multithreading and Grand Central Dispatch on iOS for Beginners Tutorial

    Have you ever written an app where you tried to do something, and there was a long pause while the U ...

  6. iOS 并发编程之 Operation Queues

    现如今移动设备也早已经进入了多核心 CPU 时代,并且随着时间的推移,CPU 的核心数只会增加不会减少.而作为软件开发者,我们需要做的就是尽可能地提高应用的并发性,来充分利用这些多核心 CPU 的性能 ...

  7. iOS - Threads 多线程

    1.Threads 1.1 进程 进程是指在系统中正在运行的一个应用程序.每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内. 比如同时打开 QQ.Xcode,系统就会分别启动两个进程. ...

  8. GCD & Operation queues & Thread

    One of the technologies for starting tasks asynchronously is Grand Central Dispatch (GCD). This tech ...

  9. usr/include/dispatch - dispatch_source

    博文一部分摘自:Parse分析,以下简称博文1(LeanCloud工程师针对Parse使用GCD的分析) 博文一部分摘自:GCD入门,以下简称博文2 建议先了解一下:BSD基础知识 在Dispatch ...

随机推荐

  1. jq仿ps颜色拾取功能-js颜色拾取

    1.效果展示 2.html代码:index.html <!DOCTYPE html> <html lang="en"> <head> <m ...

  2. 编译Linux使用的.a库文件

    编译Linux使用的.a库文件 首先是须要编译成.a的源文件 hello.h: #ifndef __INCLUDE_HELLO_H__ #define __INCLUDE_HELLO_H__ void ...

  3. oracle汉字占多少字节问题

    这个其实和Oracle的配置是相关的,用以下语句查询: select * from v$nls_parameters t where t.PARAMETER='NLS_CHARACTERSET'; 可 ...

  4. 1.7-BGP②

    BGP的更新源(BGP Neighbor Update Source Address): 原则1: 在默认情况下, BGP路由器以自己路由表中,到达对方BGP邻居的地址的那条路由所指示的出接口(物理接 ...

  5. Android Message和obtainMessage的差别

    前几天须要实现一个以太网功能就看了以太网的源代码部分,看见了源代码部分在消息处理时,发现有一些不同的地方:   平时我在处理消息时:   1.首先创建Handler对象:   private Hand ...

  6. 关于require.js的用法总结

    require.js就是将多个js文件集中化处理,在要运行的HTML文件里,写入<script data-main='js/main.js' src='js/require.js'>< ...

  7. react State改变,页面却没有改变

    react 小白编程 做项目时遇到了个问题,无论我怎么查看我的action.reducer 还是 dispatch 函数,都没有发现有什么毛病.但是 debugger 的时候,state 改变了,页面 ...

  8. 【CODEFORCES】 D. CGCDSSQ

    D. CGCDSSQ time limit per test 2 seconds memory limit per test 256 megabytes input standard input ou ...

  9. cojs1101. [Vijos1369] 难解的问题==codevs 2188 最长上升子序列

    [题目描述] 在你的帮助下,蔚蓝来到了埃及.在金字塔里,蔚蓝看到了一个问题,传说,能回答出这个问题的人就能受到埃及法老的祝福,可是蔚蓝日夜奋战,还是想不出来,你能帮帮他么?(XXX: 胡扯,教主怎么可 ...

  10. IDEA Spark Streaming Kafka数据源-Consumer

    import org.apache.spark.SparkConf import org.apache.spark.streaming.kafka.KafkaUtils import org.apac ...