POSIX线程编程指南
在UNIX/Linux系统中,线程编程是开发应用必须具备的知识,最近看到一篇关于POSIX 线程编程的资料,觉得对初学者有很大的帮组,试着把它翻译出来,原文在下面的链接中:
POSIX Threads Programming:
https://computing.llnl.gov/tutorials/pthreads/
|
- 摘要
- Pthreads 概述
- Pthreads API
- 编译 Threaded 程序
- 线程管理
- 互斥(Mutex) 变量
- 条件变量(Condition Variables)
- LLNL信息和建议
- 未包括的 主题
- Pthread 库例程参考
- 参考和更多的信息
- 练习
摘要 |
在共享内存的多处理器架构中(SMPs),线程可以用来实现并行机制。从前,硬件提供商利用他们自己私有的线程版本。对开发者,为了来实现程序的可移植性。 在UNIX系统中, IEEE POSIX 1003.1c 标准定义了一个标准的C语言线程编程接口。遵从此标准的应用被叫做POSIX threads, 或者叫 Pthreads。
本指南介绍了Pthreads的概念、动机和如果设计使用它。 Pthreads API包括三个主要方面:线程管理、互斥和条件变量。在整个过程中,面向一个新的Pthreads开发者而编写了许多示例代码来展示怎样使用Pthreads。包括讨论和示例在IBM SMP 环境中,怎样开发hybrid MPI/Pthreads 程序。作为试验练习,也给出了各种C语言示例源代码。
水平/要求:对于应用线程进行并行编程的初学者,需要了解基本的C语言并行编程知识, 对于不太了解的,阅读EC3500: Introduction To Parallel Computing 会有很大的帮助。
Pthreads 概述 |
什么是Thread?
- 从技术的角度, 线程被定义为能被操作系统调度的一个独立的指令流,但是这意味着什么啦?
- 对于软件开发者,独立于主程序运行的"procedure"可能更好表述线程。
- 再进一步,想象主程序(a.out)包括一定数量的程序(procedures),而且所有这些procedures能够被操作系统调度,从而能同时和/或者独立的运行,那就是所说的”多线程(multi-threaded)“编程。
- 怎么实现多线程(multi-threaded)“编程啦?
- 在理解线程之前,首先需要理解UNIX进程。 进程由操作系统创建,需要相当数量的花销"overhead"。 进程包括程序资源和程序执行状态相关的信息,包括:
- 进程 ID, 进程组 ID, 用户 ID, 和组 ID
- 工作环境(Environment)
- 工作目录(Working directory).
- 程序指令(Program instructions)
- 寄存器(Registers)
- 栈(Stack)
- 堆(Heap)
- 文件描述符(File descriptors)
- 信号(Signal actions )
- 共享库(Shared libraries)
- 进程间通信手段(Inter-process communication tools) (比如:消息队列、管道、信号灯或者共享内存。
|
|
UNIX PROCESS | THREADS WITHIN A UNIX PROCESS |
- 线程存在于进程空间并使用进程的资源,能够被操作系统调度,可以作为一个独立的可执行入口,因为他们仅仅复制了保证他们能够成为可执行代码所必须的资源。
- 为实现独立的控制流,线程维护自己的:
- 堆栈指针(Stack pointer)
- 寄存器(Registers )
- 调度属性(Scheduling properties)(比如调度策略或者优先级)
- 信号
- 线程私有数据 (Thread specific data)
- 简而言之,在UNIX环境下的线程:
- 存在于一进程中,并且使用该进程资源。
- 在进程生存周期中,在OS的支持下,有自己独立的控制流程。
- 仅仅复制能够独立调度而必须的资源。
- 可以与其他线程一起独立(非独立)的共享同一进程资源。
- 如果父进程死亡或者类似的情况下,线程将会随之消亡。
- 是轻量级(lightweight)进程,因为大部分开销在创建进程时已经完成(Is "lightweight" because most of the overhead has already been accomplished through the creation of its process.)。
- 因为线程在同一进程中并且共享进程资源:
- . 一个线程改变共享资源( 比如关掉一个文件),另外所有的线程能够看到 。
- 两个指针指向同一数据。
- 读写同一内存成为可能,因此需要程序员利用明确的同步机制。
Pthreads Overview |
什么是Pthreads?
- . 在历史上,硬件厂商主要使用他们自己的私有版本的线程库,这些实现的差异非常大,以致于开发者想发出能够移植的线程应用非常困难。
- 为了能够最大限度的提高线程的性能,需要一个标准的编程接口。对于UNIX系统,IEEE POSIX 1003.1c standard (1995)定义了这样的接口。遵从此标准实现的线程被叫做POSIX线程,或者Pthreads。大部分硬件厂商现在为他们的私有接口提供额外的Pthreads API。
- Pthreads定义了一套C语言编程接口和函数调用,包括一个pthread.h头文件和一个线程库,尽管此线程库可能是其他库(比如:libc库)的一部分。
- 在POSIX标准中有几个版本,实际应用中注意你所用的线程库版本,因为不同版本之间的差别会引起问题。
Pthreads Overview |
为什么选择Pthreads?
- 使用Pthreads的主要动机是实现程序的可移植性。
- . 与创建与管理一个进程的开销相比较,一个线程可以利用更少的系统开销来创建,管理这些线程也只需要比进程少的系统资源。
例如:下面的表比较了50,000次调用fork()和pthreads_create()例程创建进程/线程的时间,单位是秒,没有经过优化。
Note: don't expect the sytem and user times to add up to real time, because these are SMP systems with multiple CPUs working on the problem at the same time. At best, these are approximations.
注意:不能期望系统时间加上用户时间就是real time,因为这是多处理器同时运行的SMP系统。这里只是近似值。
Platform | fork() | pthread_create() | ||||
real | user | sys | real | user | sys | |
AMD 2.4 GHz Opteron (8cpus/node) | 41.07 | 60.08 | 9.01 | 0.66 | 0.19 | 0.43 |
IBM 1.9 GHz POWER5 p5-575 (8cpus/node) | 64.24 | 30.78 | 27.68 | 1.75 | 0.69 | 1.10 |
IBM 1.5 GHz POWER4 (8cpus/node) | 104.05 | 48.64 | 47.21 | 2.01 | 1.00 | 1.52 |
INTEL 2.4 GHz Xeon (2 cpus/node) | 54.95 | 1.54 | 20.78 | 1.64 | 0.67 | 0.90 |
INTEL 1.4 GHz Itanium2 (4 cpus/node) | 54.54 | 1.07 | 22.22 | 2.03 | 1.26 | 0.67 |
下面是源代码:
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1327ab569c1ae82736693a50b8e33378.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1327ab569c1ae82736693a50b8e33378.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1327ab569c1ae82736693a50b8e33378.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1327ab569c1ae82736693a50b8e33378.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
- 所有的线程共享一个地址空间,在许多情况下线程间通信更有效,而且比IPC更容易使用。
- 线程应用除了获得可移植的性能,与非线程应用相比,还有下面几个优势:
- 重叠(Overlapping)系统I/O操作: 例如,一个程序可能需要长时间的I/O操作,当一个线程阻塞在一个系统I/O调用时,其他线程能够获得CPU继续运行。
- 优先级/实时调度: 更重要的任务可以取代或者中断低优先级的任务而被调度。
- 异步事件处理: tasks which service events of indeterminate frequency and duration can be interleaved. 不定次数和时间的任务可以被交叉处理,例如:一个WEB服务器可以为前一个请求传送数据的同时,还可以管理新到的请求。
- 在SMP架构中使用Pthreads 的主要动机被认为是获得最佳性能, 特别是一个应用在节点通信中使用MPI的时候。使用Pthreads来代替节点间的数据传输可以有很大性能的提高。
- 例如:
- MPI库通常使用共享内存进行节点间通信,这至少会涉及一次内存拷贝操作(进程到进程)。
- 在Pthreads中,因为线程共享同一进程的地址空间,中间没有“内存拷贝”操作和数据传输,使“内存拷贝”操作更多的变成为“缓存到CPU”或者“内存到CPU”(最坏的情况)操作,这样使通信速度更高。
- 下面列出了一些细节上的比较:
Platform | MPI Shared Memory Bandwidth | Pthreads Worst Case |
AMD 2.4 GHz Opteron | 1.2 | 5.3 |
IBM 1.9 GHz POWER5 p5-575 | 4.1 | 16 |
IBM 1.5 GHz POWER4 | 2.1 | 4 |
Intel 1.4 GHz Xeon | 0.3 | 4.3 |
Intel 1.4 GHz Itanium 2 | 1.8 | 6.4 |