进程与同一进程的其他线程共享代码段、数据段和其他操作系统资源,如打开文件和信号。每个传统或重量级进程只有单个控制线程。如果一个进程具有多个控制线程,那么它能同时执行多个任务。
图 1 说明了传统单线程进程和多线程进程的差异。
图 1 单线程进程和多线程进程
现代计算机运行的大多数应用软件都是多线程的。一个应用程序通常作为具有多个控制线程的一个进程来实现。
例如,一个 Web 浏览器可能有一个线程来显示图像和文本,另一个线程从网络接收数据。一个字处理器可能有一个线程用于显示图形,另一个线程用于响应用户的键盘输入,还有一个线程在后台进行拼写和语法检查。应用程序也可以设计成利用多核系统的处理能力。这些应用程序可以在多处理核上并行执行多个 CPU 密集型的任务。
在有些情况下,单个应用程序可能需要执行多个类似任务。例如,一个 Web 服务器接收有关网页、图像、声音等的客户请求。一个繁忙 Web 服务器可能有多个(可能数千个)客户并发访问它。如果一个 Web 服务器作为单个线程的传统进程来执行,那么只能一次处理一个请求;这样,客户可能需要等待很长时间,以便请求得到处理。
一种解决方法是让服务器作为单个进程运行以便接收请求。当服务器收到请求时,它会创建另一个进程以便处理请求。事实上,这种进程创建方法在线程流行之前很常见。不过,进程创建很耗时间和资源。如果新进程与原进程执行同样的任务,那么为什么要承担所有这些开销?
通常,使用一个包含多个线程的进程更加有效。如果 Web 服务器进程是多线程的,那么这种服务器可以创建一个单独线程,以便监听客户请求。当有请求时,服务器不是创建进程而是创建线程以处理请求,并恢复监听其他请求,见图 2。
图 2 多线程的服务器架构
线程在远程过程调用(RPC)系统中,也起着至关重要的作用。RPC 通过提供一种类似于普通函数或子程序调用的通信机制,以允许进程间通信。
通常,RPC 服务器是多线程的。当一个服务器收到消息时,它使用一个单独线程来处理消息。这允许服务器处理多个并发请求。
最后,大多数的操作系统内核现在都是多线程的。多个线程在内核中运行,每个线程执行一个特定任务,如管理设备、管理内存或处理中断。例如,Solaris 有一组内核线程以处理中断,Linux 采用一个内核线程以便管理系统空闲内存的数量。
线程的优点
多线程编程具有如下四大类的优点:
- 响应性:如果一个交互程序采用多线程,那么即使部分阻塞或者执行冗长操作,它仍可以继续执行,从而增加对用户的响应程度。这对于用户界面设计尤其有用。例如,当用户点击一个按钮以便执行一个耗时操作时,想一想会发生什么事。一个单线程应用程序对用户反应会迟钝,直到该操作完成。与之相反,如果耗时操作在一个单独线程内执行,那么应用程序仍可响应用户。
- 资源共享:进程只能通过如共享内存和消息传递之类的技术共享资源。这些技术应由程序员显式地安排。不过,线程默认共享它们所属进程的内存和资源。代码和数据共享的优点是:它允许一个应用程序在同一地址空间内有多个不同活动线程。
- 经济:进程创建所需的内存和资源分配非常昂贵。由于线程能够共享它们所属进程的资源,所以创建和切换线程更加经济。虽然进程创建和管理与线程创建和管理的开销差异的实际测量较为困难,但是前者通常要比后者花费更多时间。例如,对于 Solaris,进程创建要比线程创建慢 30 倍,而且进程切换要比线程切换慢 5 倍。
- 可伸缩性:对于多处理器体系结构,多线程的优点更大,因为线程可在多处理核上并行运行。不管有多少可用 CPU,单线程进程只能运行在一个 CPU 上。
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/21194.html