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

来源:互联网 发布:淘宝回收手机被骗 编辑:程序博客网 时间:2024/06/07 11:57
多线程编程中的一个大麻烦是线程间的资源争夺。如果多个线程同时修改一份资源,问题就来了。减少问题的方法之一就是减少共享资源,保 证每个线程都有自己的一份资源可以使用。当然,管理完全独立的资源是不可能的,因此,我们要用到锁(locks),条件控制(conditions),原 子操作(atomic operations)等技术自己控制线程对资源同步的访问。


“锁”为代码提供了“暴力”的保护方式,在同一时 刻,代码只能被一个线程执行。其中,“互斥锁”是最常用的一种形式,也被叫做互斥体(mutex)。当一个线程试图获取被其他线程占用的互斥体时,该线程 会被阻塞,直到互斥体被释放。几个系统框架提供对互斥体的支持,而它们都基于同样的底层技术。Cocoa提供额外的几种互斥体来支持不同的操作,比如递归 操作。更多信息,请参考“Locks.”


除了锁以外,系统支持条件控制。它可以保证程序中任务按照正确的顺序执行。条件控制就像一个“门 卫”,它会一直阻塞某个线程。直到特定的条件为真,才允许线程继续执行。POSIX层和Foundatoin框架都直接支持条件控制。(如果你使用操作对 象(operation object),你可以设置它们之间的依赖关系,从而起到设置任务操作顺序的目的,这和条件控制很类似)。


并行 程序设计中,还可以使用“原子操作”(atomic operation)来保护、同步对数据的访问。原子操作提供了一种轻量级的锁定方案,在对某些标量数据进行数学运算或逻辑运算的时候,就可以使用原子操 作。原子操作会使用特定的硬件指令来保证对于某个变量的修改完成后其他的线程才能继续访问。


关于同步工具的详细信息,请查看“Synchronization Tools.”


线程间通信
虽 然好的设计会尽可能减少线程间的通信,但是在某些情况下,线程间的通信是必要的(线程的任务就是为程序工作,但是如果线程的运行结果无法被使用,会有什么 影响?)线程可能需要执行新的工作请求或是向程序主线程回报工作进度。在这些情况下,你就需要把一个线程的信息传递给另外一个线程。幸运的是,程序中的线 程共享同一个进程空间,这意味着你有很多种通信方案。


线程间通信有很多方式,各有优劣,“Configuring Thread-Local Storage” 表中罗列了在Mac OS X上常用到的通信机制(除了消息队列(message queue)和Cocoa分布式对象(Cocoa distributed object)外,其他也可以在iOS上通用)。详细列表如下:


Table 1-3  Communication mechanisms
Direct messaging|Cocoa程序支持直接在其他线程中执行方法(perform selector)。这个功能意味着一个线程可以直接在另外一个线程中执行方法。因为要在目标线程中执行,通过这种方法发送的消息会在线程中被自动序列 化。关于input sources的详细信息,请查看“Cocoa Perform Selector Sources.”(后章会有详细说明)。


Global variables, shared memory, and objects |另外一种通信的方式就是使用全局变量、共享对象,或是共享内存块。虽然共享变量既快又简单,这种方式相比较直接消息方式更加脆弱。必须使用锁或者其他同 步机制来“保护”共享变量。否则,可能导致线程间的竞争状态、数据被损坏,或程序崩溃。


Conditions|条件空之是控制线程同步的另一个工具。可以把条件控制看做是一个“门卫”,它只会在特定条件符合的时候才允许线程执行。更多信息,请查看“Using Conditions.”


Run loop sources |在线程中加入运行回路源可以让你接收到程序的特定消息。由于运行回路是“事件驱动”的,它会在无事可做的时候会自动让线程休眠,从而提高线程运行的效率。更多关于运行回路和运行回路源的信息,请查看“Run Loops.”


Ports and sockets |基于端口的通信是一种更加复杂的方式,但是它非常稳定。更重要的是,端口和套接字可以被在外部实体的访问,比如说其他的进程(process)和服务 (service)。为了提高效率,端口使用运行回路源协助执行,因此线程在端口上无等待数据的时候会自动休眠。更多关于运行回路和基于端口的输入源 (input source)方面的信息,请查看“Run Loops.”


Message queues| 多进程的服务中定义了一中先进先出(FIFO)队列的抽象模型来管理接收和传出的数据。虽然消息队列简单且方便,但它不像其他通信技术那样高效。关于如何 使用消息队列,请查看Multiprocessing Services Programming Guide.


Cocoa distributed objects|分布式对象是Cocoa技术中的一项,它为基于端口通信的实现提供了一种高级的方式。虽然也可以把分布式对象用在线程间通信中,但是不建 议这样做,因为会导致很高的系统开销。分布式对象在进程间通信中可以很好的排上用场,因为进程间通信本身就已经有较高的开销了。更多信息,请查看 Distributed Objects Programming Topics.
原创粉丝点击