Concurrency Programming Guide 并发设计指引(三)

来源:互联网 发布:初中答题软件 编辑:程序博客网 时间:2024/06/05 14:56

以下翻译是本人通过谷歌工具进行翻译,并进行修正后的结果,希望能对大家有所帮助。如果您发现翻译的不正确不合适的地方,希望您能够发表评论指正,谢谢。转载请注明出处。


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.

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.

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, see “Dispatch Queues.” For more information about blocks and their benefits, see Blocks Programming Topics.

调度队列 Dispatch Queue
    调度队列是基于C语言的机制,用于执行自定义任务。一个调度队列执行任务,无论是串行或并行,但始终处于一种先入先出的顺序。 (换句话说,一个调度队列总是从队列中取出,并开始以相同的顺序在它们被添加到队列中的任务。)串行调度队列中只能运行一个任务在同一时间,并开始等待,直到任务完成后出列开始执行新的任务。相比之下,并发调度队列可以开始尽可能多的任务而无需等待已经开始的任务完成。Dispatch Queue还有其他的好处:
    1.提供简单直接的设计接口
    2.支持自动全方位的线程池管理
    3.They provide the speed of tuned assembly.(怎么翻译啊)
    4.具有更有效的内存(因为线程堆不在应用内存中过分逗留)
    5.在未满载事不会对内核造成困扰。
    6.异步任务调配不会造成死锁
    7.资源竞争时可以优雅的调整
    8.串行调度队列提供了一个更有效的替代锁和其他的同步基原

您提交到调度队列的任务必须被封装在一个函数或块对象。块对象是一个C语言引入的功能在OS X v10.6中和iOS4.0函数指针的概念上是相似的,但有一些额外的好处。你通常定义块在另一个函数或方法,使他们能够访问其他变量,函数或方法,而不是在自己的词法范围定义块。块也可以搬出他们原来的范围,并复制到堆上,这是发生了什么,当你提交给调度队列。所有这些语义使人们有可能实现非常动态的任务,以相对较少的代码。
调度队列大中央调度技术的一部分,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:

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, see “Dispatch Sources.”


Dispatch Sources
Dispatch Sources是基于C的异步处理特定类型的系统事件的机制。Dispatch Sources封装特定类型的信息系统事件,每当事件发生时,调度队列提交一个特定的块对象或函数。您可以使用Dispatch Sources,以监视下列类型的系统事件:

定时器
信号处理
描述符相关的事件
流程相关的事件
Mach端口事件
自定义事件触发
Dispatch Sources是GCD技术的一部分。如需使用dispatch调度源接收事件在你的应用程序的详细信息,请参阅“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.

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 objects generate key-value observing (KVO) notifications, which can be a useful way of monitoring the progress of your task. Although operation queues always execute operations concurrently, you can use dependencies to ensure they are executed serially when needed.

For more information about how to use operation queues, and how to define custom operation objects, see “Operation Queues.”


操作队列
操作队列是Cocoa中相当于并发调度队列和由NSOperationQueue类实现。鉴于调度队列总是先入先出的顺序执行任务,运行队列需要等因素综合考虑,确定任务的执行顺序。在这些因素中主要是一个给定的任务依赖于其他任务的完成。您可以配置依赖定义任务时,可以使用它们来创建复杂的任务的执行顺序图。

您提交的操作队列的任务必须是NSOperation的类的实例。操作对象是你要执行的工作和其他需要执行的任何数据封装成Objective-C对象。因为NSOperation的类本质上是一个抽象基类,你通常定义自定义的子类来执行任务。然而,Foundation框架包括一些具体的子类,你可以创建和使用子类来执行任务。

操作对象生成键 - 值观察( KVO)通知的,它可以是一个有用的方法监测你的任务进度。虽然操作队列总是同时执行操作,您可以使用依赖,以确保它们串行执行的,在需要的时候。

有关如何使用操作队列,以及如何定义自定义操作对象欲了解更多信息,请参阅“操作队列。 ”

Asynchronous Design Techniques

Before you even consider redesigning your code to support concurrency, you should ask yourself whether doing so is necessary. Concurrency can improve the responsiveness of your code by ensuring that your main thread is free to respond to user events. It can even improve the efficiency of your code by leveraging more cores to do more work in the same amount of time. However, it also adds overhead and increases the overall complexity of your code, making it harder to write and debug your code.

Because it adds complexity, concurrency is not a feature that you can graft onto an application at the end of your product cycle. Doing it right requires careful consideration of the tasks your application performs and the data structures used to perform those tasks. Done incorrectly, you might find your code runs slower than before and is less responsive to the user. Therefore, it is worthwhile to take some time at the beginning of your design cycle to set some goals and to think about the approach you need to take.

Every application has different requirements and a different set of tasks that it performs. It is impossible for a document to tell you exactly how to design your application and its associated tasks. However, the following sections try to provide some guidance to help you make good choices during the design process.

异步设计技术

在你考虑重新设计你的代码来支持并发之前,你应该问自己是否这样做是必要的。并发可以提高你的代码,确保你的主线程响应用户事件的响应。凭借更多的内核,在相同的时间内做更多的工作,它甚至可以改善你的代码的效率。然而,这也增加了开销,并增加了整体的代码的复杂性,使得它更难编写和调试代码。

因为它增加了复杂性,在应用产品周期结束时,并发性并不是一个你可以移植的功能。想要做得正确,需要仔细考虑您的应用程序执行的任务和来执行这些任务使用的数据结构。操作不当,你可能会发现你的代码运行比以前慢,减少了用户的响应。因此,它是值得您在设计周期的开始时花一些时间,设定了一些目标,想想你需要采取的方法。

每个应用程序都有不同的要求和不同的系列任务。一个文档不可能确切地告诉你如何设计你的应用程序及其相关的任务。但是,下面的部分试图提供一些指导,帮助你在设计过程中做出正确的选择。

Define Your Application’s Expected Behavior
Before you even think about adding concurrency to your application, you should always start by defining what you deem to be the correct behavior of your application. Understanding your application’s expected behavior gives you a way to validate your design later. It should also give you some idea of the expected performance benefits you might receive by introducing concurrency.

The first thing you should do is enumerate the tasks your application performs and the objects or data structures associated with each task. Initially, you might want to start with tasks that are performed when the user selects a menu item or clicks a button. These tasks offer discrete behavior and have a well defined start and end point. You should also enumerate other types of tasks your application may perform without user interaction, such as timer-based tasks.

After you have your list of high-level tasks, start breaking each task down further into the set of steps that must be taken to complete the task successfully. At this level, you should be primarily concerned with the modifications you need to make to any data structures and objects and how those modifications affect your application’s overall state. You should also note any dependencies between objects and data structures as well. For example, if a task involves making the same change to an array of objects, it is worth noting whether the changes to one object affect any other objects. If the objects can be modified independently of each other, that might be a place where you could make those modifications concurrently.

定义你的应用程序的预期行为
在你想加入并发到您的应用程序之前,你应该总是首先定义你认为什么是正确的行为在你的应用程序中。了解您的应用程序的预期行为,为您提供了一种方法来验证您的设计。通过引入并发它也应该给你一些收到预期的性能优势想法。

你应该做的第一件事是枚举应用程序执行的任务和每个任务相关的对象或数据结构。最初,您可能要开始枚举的任务是例如用户选择一个菜单项,或者点击一个按钮。这些任务提供离散的行为,并在一个定义良好的起点和终点。你也应该列举你的应用程序可能没有用户交互的情况下执行任务,如基于计时器的任务的其他类型。

你有你的高层次的任务列表后,开始打破每一个任务分解成完成任务所必须采取的一系列步骤。在这个层面上,你应该主要关注的是你需要做的任何数据结构和对象的修改,这些修改如何影响应用程序的整体状态。您还应该注意的对象和数据结构之间的依赖关系。例如,如果一个任务涉及到的对象的数组进行相同的更改,值得注意的一个对象变化是否影响的任何其他对象。如果对象可以彼此独立的修改的,这可能是一个你可以同时做这些修改地方。

原创粉丝点击