POSIX多线程编程概述

来源:互联网 发布:诺思隐形眼镜知乎 编辑:程序博客网 时间:2024/05/11 03:01

多线程编程概述

线程是指机器指令,顺序 属性的集合. 一个线程包含一系列及其指令所必须的机器状态. 包括当前指令位置,地址和数据寄存器.
一个unix进程可以理解为线程加上地址空间,文件描述符和其他数据.某些unix版本支持轻量级和变量级进程,以便可以从进程中剔除部分或者所有数据,从而实现高效的性能.(本段简短描述了线程和进程的具体实体的样子)

异步:任何彼此 独立的运行操作都是异步的.

本章框架:

1.1 线程的工作模式

1.2 术语,最重要的概念(异步)

1.3 如何经历异步编程的

1.4 一些实例

1.5 时钟程序几种实现方式

1.6 线程模型的基本优点

1.7 线程可能的代价

1.8 要不要线程?

1.1 线程的工作模式(舀水的程序员)

故事关键词: 程序员(能独立活动的实体)  舀水的桶和划船的桨(令牌) 轻推和喊叫(通信机制)(小例子说明线程来自生活中原理)

1.2术语

**异步**:表明事情相互独立的发生**并发**:意思是事情同时发生.是指让实际可能串行发生的事情好像同时发生一样.**并行**:并行和并发在日常语言中是相同的意思,在计算机中,并行补充含义是事情在相同方向上独立运行(没有交错).真正的并行只能在多处理系统中存在.并行要求程序同时执行多个操作,而并发只要求程序能够假装同时执行多个操作.**单处理器**:一台计算机只有一个编程人员可见的执行单元(包括超标量体系结构)**多处理器**:一台计算机拥有多个处理器,他们共享同一个指令集和相同的物理内存.**线程的安全**:指代码能够被多个线程调用而不会产生灾难性的结果,不要求代码在多个线程中高校的运行只要求能够安全的运行.可以通过函数调用的串行化实现线程的安全,更有效的方式是将线程函数分为多个小的临界区,这样就允许多个线程进入函数. 更有效的方式是将代码改造为对临界数据的保护 ,这样就可以保证不会同时访问相同临界数据的线程完全并行的执行.(举个putchar的例子)**可重入**:有时用来表示"有效的线程安全",即通过采用比将函数或库转换成一系列区域更加复杂的方式使代码成为线程安全的.通过引入互斥量和线程私有数据可以实现线程安全.也尽量不调用其他不可重入的函数.应用程序中对其操作进行精准控制.以下是任何并发系统都应该具有的这种基本功能.(线程系统三要素)1)"执行环境"是并发实体的状态.并发系统必须提供建立,删除执行环境和独立维护他们状态方式的.它必须能够不时的保存好一个执行环境而去执行另一个环境.2)调度决定给定时刻应该执行哪一个环境,并在不同的环境中切换.3)同步机制:为并发执行的环境提供了协调访问资源的一种机制.线程 互斥量 条件变量是本书的主要话题.

1.3 如何经历异步编程(如何从进程过度到线程的)

时间就是同步机制Unix管道和文件可以是同步机制.例如 ls|more 两个命令可以同时执行.Unix命令本身提供同步机制.例如编译命令cc -o thread thread.c 可能涉及多个进程.多个过程可以同时启动. 由管道或中间文件来同步他们.进程中包含了需要执行代码的所有信息,所以可以异步执行.操作系统可以保存一个进程的状态转而执行其他进程不会有任何的影响.进程还包含了与执行环境不相关附加状态数据,如地址空间和文件描述符.线程就是进程里足以执行代码的部分.线程比进程简单,线程间切换比进程间切换要快的多.在很大程度上得意于线程间共享地址空间的事实.当进程进行切换时候,与进程相关的硬件状态都会失效或改变.如数据缓存和虚拟内存都需要刷新.线程间程序不同部分间高带宽通信更加容易.你不需要担心类似管道之类的消息传送机制或者不同地址空间中共享内存指针的一致性.同步更块.编程更加自然,比如你打开或创建一个文件,所有的线程都可以使用它.如果你通过malloc分配了一块动态数据结构.就可以把地址传给其他线程.让其他线程利用该结构.线程可以更方便的利用并发的优点.在多线程编程中可能要熟悉一些基本概念: 互斥量,条件变量,竞态条件,死锁和优先级倒置.

1.4 1.5 线程编程实例(闹钟程序)(比较线程与进程编程)

fork()版本和pthread版本.比较: 在fork的版本中,每个闹铃都有从主进程拷贝道独立的地址空间.多线程中所有线程共享同一个地址空间. 在fork的版本中主程序需要waitpid函数或者其他的wait函数来告诉系统释放其创建的子进程的资源.在线程当中不需要等待线程结束除非需要线程的返回值.所以线程在结束后会立刻回收.实际的运用当中系统可不能创造那么多的线程的.但是一个进程当中可以成千上百个线程.强调以下,线程之间传递数据要比进程传递数据要快的多,因为不许要映射共享内存,不需要通过管道进行读写,不需要进程间传送地址的指针是否一致.线共享一切.

1.6 线程的好处

除了并行性对硬件有一定的要求以其他方面对硬件没有要求.允许程序在等待IO操作期间可以执行其他的操作.虽然传统的异步IO有更好的效率方面的表现,但是利用线程编写的异步代码比传统的异步编程技术要简单的多.有些异步IO的实现只不过是将IO请求在线程缓冲池中分发而已.线程模型能够将独立或者松耦合的功能执行流显示的分离.

1.7 线程的代价

 线程的代价包括线程间同步所导致的直接影响.还可能包含更多细微的影响.如果你创建的计算密集型线程比可用的处理器多,则可能比多线程获得更好的程序结构,但是程序性能可能会更糟,这是由于增加了额外的同步和调度的开销. 编程设计过程需要明白同步协议和程序中的不变量,你不得不避免死锁,竞争和优先级倒置. 如果使用的库函数支持回调函数,那么必须确保库函数和回调函数是线程安全的. 需要一定的编程经验和编程规则,多线程程序将更加难以调试.

1.8 什么时候选择线程:

最适合使用线程的是实现以下功能的应用:1. **计算密集型应用**:为了能在多处理器系统上运行,将这些计算分解到多个线程中实现.2. **IO密集型应用**.将IO操作重叠,很多线程可以等待不同的IO操作.分布式服务器就是很好的实例,他们必须响应多个客户的请求.

1.9 POSIX 线程的概念

线程系统的三要素:**执行环境**,**调度**,**和同步**.比较两个线程系统可以比较他们对这三个方面的支持程度开始.类型和接口:| pthread_t        |  线程标示符 || pthread_mutex_t  | 互斥量     | | pthread_code_t   | 条件变量    | | pthread_key_t    | 线程私有权握访问键 || pthread_attr_t   | 线程属性对象 || pthread_mutexattr_t | 互斥变量属性对象 || pthread_condattr_t  |  条件变量属性对象||pthread_once_t       |  一次性初始化的控制变量|错误检查来自书籍: Programming with posix Threads. Author: David R. Butenhof
原创粉丝点击