线程的问题,调度队列,调度source,操作队列

In the early days of computing, the maximum amount of work per unit of time that a computer could perform was determined by the clock speed of the CPU. But as technology advanced and processor designs became more compact, heat and other physical constraints started to limit the maximum clock speeds of processors. And so, chip manufacturers looked for other ways to increase the total performance of their chips. The solution they settled on was increasing the number of processor cores on each chip. By increasing the number of cores, a single chip could execute more instructions per second without increasing the CPU speed or changing the chip size or thermal characteristics. The only problem was how to take advantage of the extra cores.

在计算的早期,单位时间内每台计算机的最大工作量取决于CPU的运行速度。但是随着技术的进步和处理器的设计越来越紧凑。散热和其他物理限制开始限制CPU的最大运行效率。因此,芯片制造商找到了其他的方式来提高芯片的性能。他们的解决方案是增加单芯片上的内核数量。通过增加内核数量,单芯片可以可以执行更多指令,而不增加CPU速度和改变芯片大小和热特性。仅有的问题是怎样充分利用多核。

In order to take advantage of multiple cores, a computer needs software that can do multiple things simultaneously. For a modern, multitasking operating system like OS X or iOS, there can be a hundred or more programs running at any given time, so scheduling each program on a different core should be possible. However, most of these programs are either system daemons or background applications that consume very little real processing time. Instead, what is really needed is a way for individual applications to make use of the extra cores more effectively.

为了充分利用多核,计算机需要同时执行多个任务的软件。对于一个现代的多任务的系统像OS X和iOS,在给定的时间有一百多个项目在运行。因此在不同的核心上安排每个项目是可能的。然而,程序中的大多数或者是系统维护程序或者是后台程序,他们消耗非常少的时间。相反,真正需要一种方式是单个的程序更加有效的利用多核。

The traditional way for an application to use multiple cores is to create multiple threads. However, as the number of cores increases, there are problems with threaded solutions. The biggest problem is that threaded code does not scale very well to arbitrary numbers of cores. You cannot create as many threads as there are cores and expect a program to run well. What you would need to know is the number of cores that can be used efficiently, which is a challenging thing for an application to compute on its own. Even if you manage to get the numbers correct, there is still the challenge of programming for so many threads, of making them run efficiently, and of keeping them from interfering with one another.

应用程序传统的利用应用程序的方式是创建多线程。然而,随着多核数量的增长,多线程的解决方案存在了问题。最大的问题是,线程代码到任意多核扩展的不是很好。你不能创建和内核一样的数量,并且让他们让线程跑的非常好。你需要知道的是可以高效利用的核心数量。这让应用程序自行计算是一个挑战。即使你可以正确管理内核数量,在如此多的线程里边能够高效运行依然是一个挑战,使得他们不被其他线程锁干扰。

So, to summarize the problem, there needs to be a way for applications to take advantage of a variable number of computer cores. The amount of work performed by a single application also needs to be able to scale dynamically to accommodate changing system conditions. And the solution has to be simple enough so as to not increase the amount of work needed to take advantage of those cores. The good news is that Apple’s operating systems provide the solution to all of these problems, and this chapter takes a look at the technologies that comprise this solution and the design tweaks you can make to your code to take advantage of them.

因此,为了总结问题,对于应用程序来说,需要一种充分利用多核的方法。被一个应用程序执行的大量任务也需要动态的分配来适应系统条件的变化。解决方案必须足够简单,在利用多核时,不要增加大量的工作量。好消息是,Apple操作系统提供了这一切的解决方案。本章将要介绍包含解决方案的技术和你可以利用你的代码进行设计调整来利用他们。

The Move Away from Threads

脱离线程

Although threads have been around for many years and continue to have their uses, they do not solve the general problem of executing multiple tasks in a scalable way. With threads, the burden of creating a scalable solution rests squarely on the shoulders of you, the developer. You have to decide how many threads to create and adjust that number dynamically as system conditions change. Another problem is that your application assumes most of the costs associated with creating and maintaining any threads it uses.

虽然线程已经存在了很多年,并且继续使用他们,但是他们并没有解决这个非常一般的问题:以一种可扩展的方式执行多任务。使用多线程,实现一个可扩展的解决方案的负担完全压在了开发者身上。随着系统条件的情形的变化,你来决定创建线程和动态调整线程数。另外一个问题是,你的程序承担了创建和维护线程的大部分成本。

Instead of relying on threads, OS X and iOS take an asynchronous design approachto solving the concurrency problem. Asynchronous functions have been present in operating systems for many years and are often used to initiate tasks that might take a long time, such as reading data from the disk. When called, an asynchronous function does some work behind the scenes to start a task running but returns before that task might actually be complete. Typically, this work involves acquiring a background thread, starting the desired task on that thread, and then sending a notification to the caller (usually through a callback function) when the task is done. In the past, if an asynchronous function did not exist for what you want to do, you would have to write your own asynchronous function and create your own threads. But now, OS X and iOS provide technologies to allow you to perform any task asynchronously without having to manage the threads yourself.

不依赖线程,OS X和iOS采用了异步设计来解决并发问题。异步函数再操作系统中已经存在很多年了,常常被用来启动一些耗时的任务,例如从磁盘读取数据。当调用的时候,异步函数在后台做一些操作以启动任务,但是在任务可能实际完成之前返回。通常,这涉及到从后台获取线程,在这个线程上启动。在线程执行完成之后发送一个通知。在过去,一个异步函数不存在你想做的任务。你必须写你的异步函数并且创建自己的线程。但是现在,OS X 和 iOS提供了技术方法使得你执行异步任务而没必要管理自己去管理线程。

One of the technologies for starting tasks asynchronously is Grand Central Dispatch (GCD). This technology takes the thread management code you would normally write in your own applications and moves that code down to the system level. All you have to do is define the tasks you want to execute and add them to an appropriate dispatch queue. GCD takes care of creating the needed threads and of scheduling your tasks to run on those threads. Because the thread management is now part of the system, GCD provides a holistic approach to task management and execution, providing better efficiency than traditional threads.

启动异步的技术之一就是GCD,这种技术在程序中正常书写就会达到系统层级。你需要做的就是把你想要执行的任务添加到队列中。GCD负责创建必要的线程,调度你的任务在在线程执行。因为线程管理现在是系统的一部分。GCD提供了全套的管理和执行线程,比传统的thread更加的高效。

Operation queues are Objective-C objects that act very much like dispatch queues. You define the tasks you want to execute and then add them to an operation queue, which handles the scheduling and execution of those tasks. Like GCD, operation queues handle all of the thread management for you, ensuring that tasks are executed as quickly and as efficiently as possible on the system.

Operation queues是oc对象很像调度队列,你定义你想要的任务然后添加到Operation queues。该操作队列处理这些任务的调度和执行。像GCD,Operation queues为你管理所有的线程。确保尽可能快的在系统上高效执行任务。

The following sections provide more information about dispatch queues, operation queues, and some other related asynchronous technologies you can use in your applications.

以下部分提供了更多的信息包括dispatch queues, operation queues和一些在程序中可能用到的其他异步技术。

Dispatch Queues

调度队列

Dispatch queues are a C-based mechanism for executing custom tasks. A dispatch queue executes tasks either serially or concurrently but always in a first-in, first-out order. (In other words, a dispatch queue always dequeues and starts tasks in the same order in which they were added to the queue.) A serial dispatch queue runs only one task at a time, waiting until that task is complete before dequeuing and starting a new one. By contrast, a concurrent dispatch queue starts as many tasks as it can without waiting for already started tasks to finish.

调度队列是一种基于c语言的机制用来执行自定义任务。一个调度队列执行任务或者串行或者并发,但总是先进先出。换句话说,一个调度队列总是出列和执行任务按照添加到队列的方式。一个串行队列一次只能运行一个任务,等待直到任务完成在出列前,然后才能开启一个新的任务。与之相比,一个并发队列会开启尽可能多的任务无需等待开始的任务完成。

Dispatch queues have other benefits:

调度队列有其他的好处:

They provide a straightforward and simple programming interface.

它们提供了一种直接的并且简单的程序接口。

They offer automatic and holistic thread pool management.

它们提供了自动和完整的线程池管理。

They provide the speed of tuned assembly.

它们提供了快捷集成方式。

They are much more memory efficient (because thread stacks do not linger in application memory).

它们具有更高的内存运行效率。(因为线程栈不在程序栈中停留)。

They do not trap to the kernel under load.

它们不会在加载时受限于内核。

The asynchronous dispatching of tasks to a dispatch queue cannot deadlock the queue.

一个调度队列的异步调度任务不会使队列死锁。

They scale gracefully under contention.

它们会扩展的适当的规模。

Serial dispatch queues offer a more efficient alternative to locks and other synchronization primitives.

串行队列为锁和和他同步原始方式提供了一种更加有效的方式。

The tasks you submit to a dispatch queue must be encapsulated inside either a function or a block object.Block objects are a C language feature introduced in OS X v10.6 and iOS 4.0 that are similar to function pointers conceptually, but have some additional benefits. Instead of defining blocks in their own lexical scope, you typically define blocks inside another function or method so that they can access other variables from that function or method. Blocks can also be moved out of their original scope and copied onto the heap, which is what happens when you submit them to a dispatch queue. All of these semantics make it possible to implement very dynamic tasks with relatively little code.

你提供到一个调度队列中的任务必须封装在一个函数内或者一个block对象中。Block对象是在OS X v10.6 和 iOS 4.0中引入的c语言功能,类似于函数指针的概念,但是有一些额外功能。你一般可以定义block在其他函数或者方法中以便他们可以从本函数或方法引用其他变量,而不是在自己的语法范围内定义块。Blocks也可以移出移出他们的原始范围并且复制到堆上。当你进行提交他们到堆上的时候。所有这些使得我们可以利用非常少的代码来实现动态任务。

Dispatch queues are part of the Grand Central Dispatch technology and are part of the C runtime. For more information about using dispatch queues in your applications, seeDispatch Queues. For more information about blocks and their benefits, seeBlocks Programming Topics.

调度队列是GCD的一部分,也是C的一部分。更多信息请看其他文章。

Dispatch Sources

调度来源

Dispatch sources are a C-based mechanism for processing specific types of system events asynchronously. A dispatch source encapsulates information about a particular type of system event and submits a specific block object or function to a dispatch queue whenever that event occurs. You can use dispatch sources to monitor the following types of system events:

Dispatch sources是一种用于异步处理特定类型系统事件的基于c的机制。一个Dispatch sources把特定类型的系统事件封装成信息,然后无论什么时候这个事件发生,Dispatch sources会把block对象或者函数提交到dispatch queue中。你也可以利用Dispatch sources来监听下面的系统事件:

Timers

定时器

Signal handlers

信号处理

Descriptor-related events

描述相关事件

Process-related events

与进程相关的事件

Mach port events

端口事件

Custom events that you trigger

你触发的自定义事件

Dispatch sources are part of the Grand Central Dispatch technology. For information about using dispatch sources to receive events in your application, seeDispatch Sources.

Dispatch sources是GCD技术的一部分。在你的程序中可以利用Dispatch sources来接收事件。

Operation Queues

An operation queue is the Cocoa equivalent of a concurrent dispatch queue and is implemented by the NSOperationQueue class. Whereas dispatch queues always execute tasks in first-in, first-out order, operation queues take other factors into account when determining the execution order of tasks. Primary among these factors is whether a given task depends on the completion of other tasks. You configure dependencies when defining your tasks and can use them to create complex execution-order graphs for your tasks.

Operation Queue是等价于一个异步dispatch queue,使用NSOperationQueue实现的。然而,dispatch queues总是执行任务按照先进先出的顺序。当operation queues决定执行任务顺序的时候,会考虑其他因素。在这些因素中,主要因素是给定的任务是否依赖于其他任务的完成。无论什么时候定义你的任务,你都可以为你的任务配置依赖来创建复杂的执行顺序。

The tasks you submit to an operation queue must be instances of the NSOperation class. An operation object is an Objective-C object that encapsulates the work you want to perform and any data needed to perform it. Because the NSOperation class is essentially an abstract base class, you typically define custom subclasses to perform your tasks. However, the Foundation framework does include some concrete subclasses that you can create and use as is to perform tasks.

你提交到operation queue中的任务一定是NSOperation类的实例。一个operation对象是一个oc对象,它可以封装了你想要执行的work和执行它需要的数据。由于NSOperation本质上是一个抽象类,一般你需要自定义子类来执行你的任务。然而,Foundation framework包括具体的子类,你可以创建和使用他们来执行任务。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容