Solaris2.4 多线程编程指南1--线程基础
1线程基础
multithreading可以被翻译成多线程控制。与传统的UNIX不同,一个传统 的UNIX进程包含一个单线程,而多线程(MT)则把一个进程分成很多可执行线 程,每一个线程都独立运行。
阅读本章可以让你理解:
Defining Multithreading Terms
Benefiting From Multithreading
Looking At Multithreading Structure
Meeting Multithreading Standards
因为多线程可以独立运行,用多线程编程可以
1) 提高应用程序响应;
2) 使多CPU系统更加有效;
3) 改善程序结构;
4) 占用更少的系统资源;
5) 改善性能;
1.1定义多线程术语:
线程:在进程的内部执行的指令序列;
单线程:单线程;
多线程:多线程;
用户级线程:在用户空间内的由线程函数库进程控制的现成;
轻进程:又称LWP,内核内部的执行核代码和系统调用的线程;
绑定(bound)线程:永远限制在LWP内的线程;
非绑定(unbound)线程:在LWP动态捆绑和卸绑的线程;
记数信号量:一个基于内存的同步机制;
1.1.1定义同时(concurrency)和并行(parallism):
在进程内至少同时有两个线程进行(process)时存在同时性问题;至少同时有两个线程在执行时存在并行问题;
在单处理器上执行的多线程的进程内部,处理器可以在线程中间切换执行, 这样实现了同时执行;在共享内存多处理器上执行的同一个多线程进程,每一 个线程可以分别在不同的处理器上进行,是为并行。
当进程里的线程数不多于处理器的数量时,线程支持系统和操作系统保 证线程在不同的处理器上执行。例如在一个m处理器和m线程运行一个矩阵乘法, 每一个线程计算一列。
1.2多线程的益处
1.2.1提高应用程序响应
任何一个包含很多互不关联的操作(activity)的程序都可以被重新设计, 使得每一个操作成为一个线程。例如,在一个GUI(图形用户界面)内执行一 个操作的同时启动另外一个,就可以用多线程改善性能。
1.2.2使多处理器效率更高
典型情况下,有同时性需求的多线程应用程序不需要考虑处理器的数量。应用程序的性能在被多处理器改善的同时对用户是透明的。
数学计算和有高度并发性需求的应用程序,比如矩阵乘法,在多处理器平台上可以用多线程来提高速度。
1.2.3改善程序结构
许多应用程序可以从一个单一的、巨大的线程改造成一些独立或半独立的 执行部分,从而得到更有效的运行。多线程程序比单线程程序更能适应用户需 求的变更。
1.2.4占用较少的系统资源
应用程序可以通过使用两个或更多的进程共享内存的办法来实现多于一个 现成的控制。然而,每一个进程都要有一个完整的地址空间和操作系统状态表 项。用于创建和维护多进程大量的状态表的开销与多线程方法相比,在时间上 和空间上都更为昂贵。而且,进程所固有的独立性使得程序员花费很多精力来 实现进程间的通信和同步。
1.2.5把线程和RPC结合起来
把多线程和RPC(remote procedure call,远程过程调用)结合起来,你可以使用没内存共享的多处理器(比方说一个工作站组)。这种结构把这组工作站当作一个大的多处理器系统,使应用程序分布得更加容易。
例如,一个线程可以创建子线程,每一个子进程可以做RPC,调用另外一 台机器上的过程。尽管最早的线程仅仅创建一些并行的线程,这种并行可以包 括多台机器的运行。
1.2.6提高性能
本部分的性能数据是从SPARC station2(Sun 4/75)上采集的。测量精度为微秒。
1. 线程创建时间
表1-1显示了使用thread package做缓存的缺省堆栈来创建线程的时 间。时间的测量仅仅包括实际的生成时间。不包括切换到线程的时间。比 率(ratio)列给出了该行生成时间与前一行的比。 数据表明,线程是更加经济的。创建一个新进程大概是创建一个 unbound线程的30倍,是创建一个包含线程和LWP的bound线程的5倍。
Table 1-1 Thread Creation Times
Operation Microseconds Ritio
Create unbound thread 52 -
Create bound thread 350 6.7
Fork() 1700 32.7
2. 线程同步(synchronization)时间
表1-2列出了两个线程使用pv操作的同步时间。
Table 1-2 Thread Synchronization Times
Operation Microseconds Ratio
Unbound thread 66 -
Bound thread 390 5.9
Between Processes 200 3
1.3多线程结构一览
传统的UNIX支持现成概念--每一个进程包含一个单线程,所以用多进程就 是使用多线程。但是一个进程还有一个地址空间,创建一个新进程意味着需要 创建一个新的地址空间。
因此,创建一个进程是昂贵的,而在一个已经存在的进程内部创建线程是 廉价的。创建一个线程的时间比创建一个进程的时间要少成千倍,部分是因为 在线程间切换不涉及地址空间的切换。
在进程内部的线程间通信很简单,因为线程们共享所有的东西--特别是地址空间。所以被一个线程生成的数据可以立刻提供给其他线程。
支持多线程的接口(界面)是通过一个函数库libthread实现的。多线程通过把内核级资源和用户级资源独立开来提供了更多的灵活性。
1.3.1用户级线程
线程仅仅在进程内部是可见的,在进程内部它们共享诸如地址空间、已经 打开的文件等所有资源。以下的状态是线程私有的,即每一个线程的下列状态 在进程内部是唯一的。
.线程号(Thread ID)
.寄存器状态(包括程序计数器和堆栈指针)
.堆栈
.信号掩码(Signal mask)
.优先级(Priority)
.线程私有的存储段(Thread-private storage)
因为线程共享进程的执行代码和大部分数据,共享数据被一个线程修改之 后可以进程内的其他线程见到。当一个进程内部线程与其他线程通信的时候, 可以不经过操作系统。
线程是多线程编程的主要主要借口。用户级的线程可以在用户空间操作, 从而避免了与内核之间的互相切换。一个应用程序可以拥有几千个线程而不占 用太多的内核资源。占用内核资源的多少主要决定于应用程序本身。
在缺省情况下,线程是非常轻便的。但是,为了控制一个线程(例如,更 多地控制进程调度策略),应用程序应当绑定线程。当一个应用程序把线程的所 有执行资源绑定后,线程就变成了内核资源(参见第9页"bound 线程")。 总之,solaris用户级线程是:
.创建的低开销,因为只在运行是占用用户地址空间的虚拟内存的几个bit。
.快速同步,因为同步是在用户级进行,不需要接触到内核级。
.可以通过线程库libthread很容易地实现。
图1-1 多线程系
multithreading可以被翻译成多线程控制。与传统的UNIX不同,一个传统 的UNIX进程包含一个单线程,而多线程(MT)则把一个进程分成很多可执行线 程,每一个线程都独立运行。
阅读本章可以让你理解:
Defining Multithreading Terms
Benefiting From Multithreading
Looking At Multithreading Structure
Meeting Multithreading Standards
因为多线程可以独立运行,用多线程编程可以
1) 提高应用程序响应;
2) 使多CPU系统更加有效;
3) 改善程序结构;
4) 占用更少的系统资源;
5) 改善性能;
1.1定义多线程术语:
线程:在进程的内部执行的指令序列;
单线程:单线程;
多线程:多线程;
用户级线程:在用户空间内的由线程函数库进程控制的现成;
轻进程:又称LWP,内核内部的执行核代码和系统调用的线程;
绑定(bound)线程:永远限制在LWP内的线程;
非绑定(unbound)线程:在LWP动态捆绑和卸绑的线程;
记数信号量:一个基于内存的同步机制;
1.1.1定义同时(concurrency)和并行(parallism):
在进程内至少同时有两个线程进行(process)时存在同时性问题;至少同时有两个线程在执行时存在并行问题;
在单处理器上执行的多线程的进程内部,处理器可以在线程中间切换执行, 这样实现了同时执行;在共享内存多处理器上执行的同一个多线程进程,每一 个线程可以分别在不同的处理器上进行,是为并行。
当进程里的线程数不多于处理器的数量时,线程支持系统和操作系统保 证线程在不同的处理器上执行。例如在一个m处理器和m线程运行一个矩阵乘法, 每一个线程计算一列。
1.2多线程的益处
1.2.1提高应用程序响应
任何一个包含很多互不关联的操作(activity)的程序都可以被重新设计, 使得每一个操作成为一个线程。例如,在一个GUI(图形用户界面)内执行一 个操作的同时启动另外一个,就可以用多线程改善性能。
1.2.2使多处理器效率更高
典型情况下,有同时性需求的多线程应用程序不需要考虑处理器的数量。应用程序的性能在被多处理器改善的同时对用户是透明的。
数学计算和有高度并发性需求的应用程序,比如矩阵乘法,在多处理器平台上可以用多线程来提高速度。
1.2.3改善程序结构
许多应用程序可以从一个单一的、巨大的线程改造成一些独立或半独立的 执行部分,从而得到更有效的运行。多线程程序比单线程程序更能适应用户需 求的变更。
1.2.4占用较少的系统资源
应用程序可以通过使用两个或更多的进程共享内存的办法来实现多于一个 现成的控制。然而,每一个进程都要有一个完整的地址空间和操作系统状态表 项。用于创建和维护多进程大量的状态表的开销与多线程方法相比,在时间上 和空间上都更为昂贵。而且,进程所固有的独立性使得程序员花费很多精力来 实现进程间的通信和同步。
1.2.5把线程和RPC结合起来
把多线程和RPC(remote procedure call,远程过程调用)结合起来,你可以使用没内存共享的多处理器(比方说一个工作站组)。这种结构把这组工作站当作一个大的多处理器系统,使应用程序分布得更加容易。
例如,一个线程可以创建子线程,每一个子进程可以做RPC,调用另外一 台机器上的过程。尽管最早的线程仅仅创建一些并行的线程,这种并行可以包 括多台机器的运行。
1.2.6提高性能
本部分的性能数据是从SPARC station2(Sun 4/75)上采集的。测量精度为微秒。
1. 线程创建时间
表1-1显示了使用thread package做缓存的缺省堆栈来创建线程的时 间。时间的测量仅仅包括实际的生成时间。不包括切换到线程的时间。比 率(ratio)列给出了该行生成时间与前一行的比。 数据表明,线程是更加经济的。创建一个新进程大概是创建一个 unbound线程的30倍,是创建一个包含线程和LWP的bound线程的5倍。
Table 1-1 Thread Creation Times
Operation Microseconds Ritio
Create unbound thread 52 -
Create bound thread 350 6.7
Fork() 1700 32.7
2. 线程同步(synchronization)时间
表1-2列出了两个线程使用pv操作的同步时间。
Table 1-2 Thread Synchronization Times
Operation Microseconds Ratio
Unbound thread 66 -
Bound thread 390 5.9
Between Processes 200 3
1.3多线程结构一览
传统的UNIX支持现成概念--每一个进程包含一个单线程,所以用多进程就 是使用多线程。但是一个进程还有一个地址空间,创建一个新进程意味着需要 创建一个新的地址空间。
因此,创建一个进程是昂贵的,而在一个已经存在的进程内部创建线程是 廉价的。创建一个线程的时间比创建一个进程的时间要少成千倍,部分是因为 在线程间切换不涉及地址空间的切换。
在进程内部的线程间通信很简单,因为线程们共享所有的东西--特别是地址空间。所以被一个线程生成的数据可以立刻提供给其他线程。
支持多线程的接口(界面)是通过一个函数库libthread实现的。多线程通过把内核级资源和用户级资源独立开来提供了更多的灵活性。
1.3.1用户级线程
线程仅仅在进程内部是可见的,在进程内部它们共享诸如地址空间、已经 打开的文件等所有资源。以下的状态是线程私有的,即每一个线程的下列状态 在进程内部是唯一的。
.线程号(Thread ID)
.寄存器状态(包括程序计数器和堆栈指针)
.堆栈
.信号掩码(Signal mask)
.优先级(Priority)
.线程私有的存储段(Thread-private storage)
因为线程共享进程的执行代码和大部分数据,共享数据被一个线程修改之 后可以进程内的其他线程见到。当一个进程内部线程与其他线程通信的时候, 可以不经过操作系统。
线程是多线程编程的主要主要借口。用户级的线程可以在用户空间操作, 从而避免了与内核之间的互相切换。一个应用程序可以拥有几千个线程而不占 用太多的内核资源。占用内核资源的多少主要决定于应用程序本身。
在缺省情况下,线程是非常轻便的。但是,为了控制一个线程(例如,更 多地控制进程调度策略),应用程序应当绑定线程。当一个应用程序把线程的所 有执行资源绑定后,线程就变成了内核资源(参见第9页"bound 线程")。 总之,solaris用户级线程是:
.创建的低开销,因为只在运行是占用用户地址空间的虚拟内存的几个bit。
.快速同步,因为同步是在用户级进行,不需要接触到内核级。
.可以通过线程库libthread很容易地实现。
图1-1 多线程系
Tags:Solaris,线程,编程,指南,线程,基础

