多线程编程指南(官方文档)一

多线程编程指南


简介


1. 关于多线程编程
多年以来,计算机的性能在很大程度上被单核处理器的速度所 限制。在当前技术下,单核处理器的速度已经到达某种极限,因此,芯片制造商们转而专注于多核设计,以使计算机可以同时执行多个任务。Mac OS X 可以利用多核计算,更好的执行系统相关的任务。而开发人员也可以通过线程提高自己程序的性能。


1) 什么是线程?


线程是 在程序内部运行多个流程的轻量单位。在系统级别上,程序使用系统提供的执行时间,各自运行。然而,在每个程序内部,存在着一个或多个被执行的线程,这些线 程可以在同一时刻(或将近同时)完成不同的任务。由操作系统本身管理这些线程的执行,例如为线程分配执行时间和执行的内核,或是中断线程来使其他线程有机 会执行。


从技术角度来看,线程是“内核级”和“程序级”数据结构的集合,用来管理代码的执行。内核级的数据结构主要处理针对线程的事件,安排线程在可用的内核上执行。而程序级的结构包括调用栈(可以保存函数调用),还有用来管理和计算线程属性和状态的数据。


在 非并行程序中,只有一个线程的执行。线程起始于main函数,结束于main函数。在main函数内部,程序一句一句的执行。相比较而言,支持并行的程序 起始于一个线程,然后在添加其他线程,从而创建了额外的执行路径。每个这样的路径都拥有自己的执行过程,而和程序中的主线程并行不悖。在程序中加入多线 程,会为你带来以下两个非常重要的好处:


1. 多线程可以提高程序的反应速度。
2. 在多核系统上,多线程可以增强程序的实时处理能力。


如 果你的程序只有一个线程,这一个线程就得做所有事情。它必须响应事件、更新程序窗口、执行所有的运算工作。单线程的问题是在特定时刻内,它只能处理一件 事。那么如果我们的某些计算工作需要耗费很长时间,会发生什么?当代码忙于计算需要的值时,程序就停止对用户事件的响应,也不会再对窗口进行更新。如果时 间很长的话,用户可能以为程序卡住了,强行关闭程序。但是,如果你将需要的计算工作放到一个独立的线程中去,你的主线程就有足够的时间去响应用户事件。


在多核电脑日益普及的今天,线程提高了某些程序的性能。执行多个任务的线程可以使用不同的处理器内核,从而使增加给定时间内完成的工作量成为可能。


但 是,线程并不是改善程序性能问题的万金油。伴随着线程提供的好处,更多的潜在问题也随之产生。在程序中加入多个执行路径会大大增加代码的复杂度。每个线程 都需要协调各自的行为,来防止弄乱程序的状态。这是因为位于同一程序的所有线程共享同一个内存空间,它们对所有的这些数据结构都有访问权限。如果两个线程 同时计算一份数据,其中一个线程可能将另外线程修改的内容覆盖,那么计算结果就乱套了。即使是使用了恰当的保护方式,我们还是必须注意编译器优化选项(它 可能导致代码出现很微妙的错误)。


2)线程相关术语
在深入研究线程和相关技术之前,必须先了解一些基本术语的定义。
如果 你熟悉Carbon框架中的多核处理服务接口(Multiprocessor Services API),或是熟悉Unix系统,你将会发现术语“任务”(task)在本文档中的含义略有不同。在Mac OS的早期版本中,术语“任务”被用来区别使用Multiprocessor Services创建的和使用Carbon Thread Manager创建的线程。而在Unix系统之上,术语“任务”有时指的是运行中的进程(process)。实际情况中,一个 Multiprocessor Services的任务和一个抢占式线程是一样的(注:没有深入的用过Carbon,有不妥之处还望指正)。


考虑到Carbon Thread Manager和Multiprocessor Services的API都是在Mac OS系统上的遗留技术,本文档遵循以下的术语规范:
1. 术语线程(thread)指独立的代码执行路径。
2. 术语进程(process)指程序的运行,进程可以包括多个线程。
3. 术语任务(task)指的是一份可以被执行的工作,是个抽象概念。


3)线程备选方案
自 己创建线程时的一个问题是:它们为你的代码增加了不确定因素。线程是让程序支持并行操作的一种相对低层次的方式,而且比较复杂。如果你没有完全理解自己针 对多线成设计的初衷,就很容易遇到同步或时间控制的问题。轻者改变程序的行为,严重的会造成程序崩溃或是弄乱用户的数据。


另一个需要考虑 的因素是:你是否真的需要并行操作?线程可以解决在同一进程中同时执行多段代码的问题。在某些情况下,一些工作并不能保证被同时执行。线程可能带来更多的 负荷,有内存消耗方面的,抑或是占用CPU时间。你需要研究是否值得为某个任务承担这样的负荷,或者使用其他简单的执行方式。


Table 1-1 列出了可供选择的线程实现方式。表中包含了线程的替代技术(操作对象-- operation object 和Grand central Dispatch),还包含了旨在提高效率的单线程技术。


Table 1-1  Alternative technologies to threads
Technology   Description
Operation objects| Mac OS X v10.5后被引入,一个操作对象是一项任务的封装,可以被子线程们来执行。使用这样的封装技术,可以忽略线程管理方面的麻烦,使程序员专注于任务本身。 通常情况下,我们搭配使用操作队列对象(operation queue object)来使用操作对象。操作队列对象会管理操作对象在多线程中的执行。具体内容参考Concurrency Programming Guide.


Grand Central Dispatch |Mac OS X v10.6后被引入,Grand Central Dispatch是让我们专注于任务本身而非线程管理的另外的选择。使用Grand Central Dispatch,我们定义一项任务,并将其加入到一个工作队列中,队列会负责在合适的线程中执行任务。队列还会查看可用内核的数量和当前任务负载,从而 比自己使用线程更高效的执行任务。


Idle-time notifications |对于那些相对来说较小的、优先级低的任务,“空闲时间通知”的方式可以让你在程序空闲的时候执行它们。Cocoa用 NSNotificationQueue对象提供空闲时通知功能。要请求空闲时通知,就提交通知对象到默认的NSNotificationQueue(通 知队列)。队列会延迟提交通知对象,直到run loop空闲。更多信息请查看Notification Programming Topics.


待续。。。每天会持续更新。


Asynchronous functions |系统接口包括了很多异步函数,这些函数本身就自动支持并行操作。它们可能使用系统守护进程来创建自己的线程、执行任务并返回结果(具体的实现方式并不重 要,因为它和你的代码是分开的)。在设计程序的时候,先查查这一类支持异步操作的函数,而尽量少在自己定义的线程中用等效的同步函数。


Timers |当遇到某些需要定时执行的小任务,而且这些任务并没有动用线程的必要时,可以考虑在主线程中使用定时器。详细信息请查看“Timer Sources.”


Separate processes |尽管进程相对于线程来说有些“重量级”,如果某项任务和程序无直接关系,创建独立的进程还是有必要的。例如:任务需要申请大量的内存空间或者必须使用 root权限执行。我们还可能需要使用64位的服务器进程来计算大数据,而用32位的程序显示运行结果。


4)线程的系统支持
如果你要将线程加入到现有的代码中去,Mac OS和iOS提供了几种创建线程的技术。另外,这两个系统还为管理和同步线程内的工作提供了支持。接下来的内容描述了几种在Mac OS和iOS上使用线程的关键技术。


Listing 2-2列出了在程序中可能用到的线程技术


Table 1-2  Thread technologies
Technology
Description
Cocoa threads |Cocoa使用NSThread类来实现线程。Cocoa还为NSObject类提供了一些方法来在已有线程中生成新的线程并执行代码。更多信息,请参 考“Using NSThread” and “Using NSObject to Spawn a Thread.”


POSIX threads |POSIX线程技术提供了一系列基于C的接口来创建线程。如果你不打算编写Cocoa的程序,那么它是最好的选择。POSIX的接口相对简单易用且扩展性良好,便于自定义线程。更多信息,请参考“Using POSIX Threads”


Multiprocessing Services |Multiprocessing Services是老式的C接口。被用于支持Mac OS较早的版本。这项技术在Mac OS X上可用,但在新的开发项目中应该避免使用,而应使用NSThread和POSIX的线程技术。更多信息,请参考Multiprocessing Services Programming Guide。


从程序的层面上来看,所有线程的行为在本质上应该是一样的——无论是任何的平 台。启动线程后,线程会有这几种运行状态:正在运行(running),准备就绪(ready)和被阻塞(blocked)。如果一个线程当前未运行,那 么它可能是被阻塞,或者是在等待输入,也有可能已经就绪,但未被安排执行(scheduled)。线程会在这几个状态之间来来回回。直到真正执行完毕退 出,进入终结(terminated)状态。


当你创建一个新的线程时,你必须为其指定入口函数(在Cocoa中,叫入口方法 (method))。入口函数包括你想要在线程中执行的代码。当函数返回,或当你显式的终结线程时,线程就永远结束了,然后会被系统回收。线程在内存和时 间片占用方面代价昂贵,正因为如此,建议你在入口函数中完成大量的工作,或者自己设置一个运行回路(run loop)来循环执行工作。


更多线程可用技术的信息,请参考“Thread Management.”


运行回路(Run Loops)


运行回路是线程中管理异步事件获取的基础。它的工作是为线程监视事件源(event sources)。当事件到来之时,系统唤醒线程并将事件发送给运行回路,然后在传递给你指定的处理者。如果没有需要处理的事件到来,运行回路将线程置于休眠状态。


在 线程中使用运行回路不是必须的。但是如果这样做的话,会有更好的用户体验。使用运行回路可以创建长期存在的线程,并尽可能少的占用资源。因为运行回路在无 事可做的时候让线程休眠。它减少了轮询(polling)的需要,而轮询会浪费CPU循环数,阻止CPU休眠,从而比较耗电。


要设置一个 运行回路,你所要做的只是运行你的线程,获得一个运行回路的对象,“安装”你的事件处理者,并且告诉运行回路去运行。不管是Cocoa还是Carbon都 在主线程中自动为你提供了默认运行回路的设置。如果你需要创建一个长期存在的子线程,就需要自己来在线程里定义运行回路了。


关于运行回路的详细信息和例子,请参考“Run Loops.”。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
多线程基础介绍.........................................................................................................................................15 定义多线程术语.........................................................................................................................................15 符合多线程标准.........................................................................................................................................16 多线程的益处.............................................................................................................................................17 提高应用程序的响应.........................................................................................................................17 有效使用多处理器..............................................................................................................................17 改进程序结构.....................................................................................................................................17 占用较少的系统资源.........................................................................................................................17 结合线程和RPC(远程过程调用) ...............................................................................................18 多线程概念..................................................................................................................................................18 并发性和并行性.................................................................................................................................18 多线程结构一览.................................................................................................................................18 线程调度..............................................................................................................................................19 线程取消..............................................................................................................................................19 线程同步...............
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值