多线程,当今在IT圈子内部最普遍的概念。有多少人理解它的实质,它的精髓?(我不甚懂,这篇文章只是在使劲往前冲的时候让我停下了,吃点有营养的东西,然后继续冲)甚至在多线程还没有完全吃透的情况下,现在又冒出了什么并行计算,网格,云等等......
做技术应该迷恋技术,但不应该迷信技术!要吃透它,上升到理论的高度!
在计算机时代早期,只有任务,后来有了批处理,但是本质上还是一个任务,后来为了更加密集的应用资源产生了多道程序设计,这就开始了多进程时代,世界开始热闹了。多进程(多道程序设计)本质上是在一台硬件机器上虚拟N台硬件机器,有了N台机器,那么很自然的就可以跑N个进程了,这样,计算机领域的最伟大的 思想诞生了-----虚拟分层思想。该思想本质上是在某层(n层)通过外加一个下层(n-1层)的管理模块,向上层(n+1层)提供一个完整的抽象,这个 抽象可以让上层(n+1)的模块认为自己完全运行在下层(n-1)。这很拗口,我用实例说明一下:我把机器硬件设想为n-1层,多进程操作系统作为n层, 而应用软件为n+1层,我们看看是不是这个道理,每个进程(应用软件)都认为自己享有了整个机器,其他进程被操作系统这个管理者给隔离了,进城间通信被假象成两台不同机器的通信,所以古老又伟大的unix把套接字作为进程间通信的手段的一种。分层虚拟思想有两个很重要的层面,一个是隔离,一个是共享,很矛盾,但却是共存的,也许这就是我们的世界吧。隔离和共享再抽象一点就是个性和共性,隔离的是个性,共享的是共性。在我举的例子里面,共享的是硬 件,隔离的是进程私有的东西。按照科学界的做法,总是出一个量化的东西,那么我说:共享的是n层往下包括n层的东西(共享n-1层往下的层就没多大意义了,概念上是共享,但是注意,分层思想的另一个核心就是屏蔽,n层会为n+1层屏蔽掉n层下面层次的异构性),隔离的是n+1层的东西。这么说就很简单 了,但是这只是个开始,随着讨论的深入,我会把层次进一步的分割或合并,最终产生我们正
在用的windows或linux,或者,我的皮肤,我的家庭,或者,我们的世界.....(或者,世界之外....)。虚拟分层包括两层含义,一是虚拟,而是分层,虚拟指的是类似分形的我中有你,你中有我的一个总体结构,而分层是一个部分的,低耦合高内聚的组成实体,它对上层屏蔽下层,使用下层的接口服务为上层提供统一接口服务。
按照这个思想,多线程就有运而生了,现在已经有了:硬件(cpu等)-〉操作系统-〉进程,的层次关系了,而且在操作系统的管理之下,进程运行在操作系统提供的虚拟cpu上,同样的道理,这里把虚拟cpu当作真正的cpu的话,就可以在这个cpu(虚拟的)上实现多道程序设计了,进程作为管理者,再向上抽象一层,这就是线程!这里的进程成了属于它的线程的“操作系统”,每个线程都认为自己拥有整个虚拟cpu,所有线程实际上共享这个虚拟cpu。截至目前我 们的层次化表示为:硬件cpu-〉操作系统-〉进程-〉线程;而虚拟化表示为:硬件cpu(操作系统)-〉虚拟cpu(进程)-〉线程。这么看来,继续下 去是可行的,我们可以再进一步抽象,进程可以提供一个虚拟虚拟cpu,从学术意义上,这是很优美的,但是从技术上,却是没有意义,因为我们没有理由这么做,学术上往往从和谐和美学角度分析问题,但是在技术上,做一件事必须有一个可实施的非空洞理由!往往很多成果都是现有了理论,然后当那个理由很充分的时 候,技术上的对应物就出现了,上面谈的都是理论的东西,那么促使多道程序设计和线程出现的那个理由到底是什么呢?
最开始的时候,应用计算机就是为了计算一些数值运算,退一步说就是给它一个1,给它一个+,再给它一个1,问它结果等于几,诸如此类的问题,那么可以直接 用硬连线实现,随着半导体的发展,计算机的运算性能不断提高,仅仅用于计算大大浪费,所以就用它来做很多的事情,从而产生了批处理系统,但是一个时间做一件事情也不好,于是,多道程序设计就出现了,当时多道程序设计刚起步,人们的想法还只是很简单的隔离进程的思想,进程间通信的代价很大,就像不同机器的通 信差不多,随着时间的推移以及多道程序设计的进一步完善,加之人们共享概念的生成,很自然的需要在不同进程之间共享一些资源,所以对进程间通信提出了挑战,最终促使了多线程的产生......
基本概念我们都明白了,那么现在你能理解现实中的系统了吗?能理解intel的VT技术吗?实际上全是虚拟分层思想的套用,intel为了在其处理器上并发运行不同操作系统,那么必须在硬件和操作系统之间加一层管理层,这就是VT-xxx技术了。
注意,我上面的讨论中,丝毫没有提到存储器和IO,其实,计算和存储两大部分只是冯诺依曼机器的模型,很多并行机并非那样,如果非要说说冯诺依曼机器和虚拟分层思想的对应,那么就只有两点需要注意,一个是计算,一个是存储,负责计算的是进程或线程,负责存储的就是另一大部分了---虚拟存储器,文件和外设 IO,而虚拟存储器也是一个分层的东西。而IO为何一般不向上层抽象呢?
我们上面讨论虚拟机思想的时候说到了抽象,操作系统把cpu指令都抽象给了进程,那为什么没有把IO给进城呢?每当进程需要IO服务时,必须请求操作系统 系统调用。因为在冯诺依曼机中cpu是核心,一切控制的核心,所有控制序列都是从cpu发起的,cpu的核心就是计算,而IO设备并不具备这样的机制,形象一点说,不管是多道程序设计还是多线程都是cpu提供的机制,操作系统提供的策略,执行一条指令,cpu中的硬件逻辑(寄存器上下文)知道这个指令属于 哪个进程或者线程,而且也控制好了互斥等等,然而IO外设则不然,你发给它一条指令,它只会傻乎乎的执行,它并没有控制逻辑,它只有要么I,要么O接口, 控制逻辑是外设相关的,比如你把一个字符串写到ntfs格式磁盘和写道xfs格式磁盘,或者写道el1000网卡的格式是不一样的,
外设内在地并 不支持多进程多线程和控制逻辑,所以这么直接在进程(线程)上下文执行IO是很危险的,因此,外设不能简单地抽象给进程。我个人认为,把cpu和外设同等 对待,在外设上也加入复杂的控制逻辑,就可以将外设抽象给进程了,但是那样硬件的设计就复杂了,外设的多样性使得提供统一的指令级别的接口变得不可能,而且也违背了机制策略分离的原则(cpu提供那么多的控制功能恰恰没有问题,因为它的任务就是控制计算,而计算很大程度上接口是很容易统一的)。于是在各个处理器指令集里,io指令被称为敏感指令,而还有一些指令是无论如何,进程都不能触及的,这就是cpu控制进程或线程的特权指令。
前面说了那么多,同时又闲扯了上面这一段,还是回到多线程,我们真的该用多线程吗?我们符合多线程带来实惠的条件吗?不少人为了展示自己多懂编程,动不动就pthread_create,包括我也一样,当你真正理解多线程以后,看过多线程的实现以后,你会不禁一叹!多线程建立销毁的开销,多线程切换的开销,多线程互斥的开销,你富裕到足够消费这些的程度了吗?如果你仅仅拥有单cpu,那么对于cpu密集型的计算只会徒增复杂性和开销而已,到头来程序更 慢,对于io密集型的计算,多线程倒是个好主意,因为一个在等io的时候另一个可以进行计算,单cpu上,线程就是时间片。考虑一下在只有一个经理的情况下,他要处理5个文件,如果他一心一意处理文件,没有别的打扰,而且他从不停顿的话,是让一个人把5个文件一下子全部拿来好呢,还是5个人每人拿一份文 件,一次进去一个人送一份文件,等经理处理完后让他出去叫另一个拿文件进来好呢?计算机里面的东西在现实中都有相应的模型,比如找零钱问题,处理器流水线....如果你在现实世界没有找到一个模型或者说和现实世界的做法背道而驰,而把它引入计算机系统的话,那将不是一个好的主意!
最后推荐两篇文章,本来我准备写点相关的东西呢,后来没有时间了,于是共享一把别人的资源:
操作系统系列之概述 (http://fixopen.javaeye.com/blog/27850)
多线程是个不靠谱的东西(http://www.javaeye.com/topic/189994)
分享到:
相关推荐
程序,进程和线程的区别---马克-to-win java视频的详细介绍
在"进程与线程--小练习"这个主题中,可能包含了一些实践性的例子,比如创建和管理进程、线程的示例,或者展示了如何使用操作系统提供的API来实现进程间通信和线程同步。这些练习可以帮助学习者更好地理解和掌握进程...
在Java编程领域,多线程和进程是两个关键的概念,对于任何有志于从事Java开发的程序员来说,理解和掌握它们至关重要。以下是对73道Java面试题合集——多线程与进程相关知识点的详细解释。 1. **进程与线程的概念**...
### Linux 下进程、线程与 fork 的深入理解 #### 题目背景及解析 本篇文章将基于一道经典的面试题目来探讨 Linux 下进程创建机制,特别是 `fork` 函数的工作原理。该题目不仅考验应试者对进程创建的理解,还涉及了...
### 线程和进程的区别 #### 进程与线程的基本概念 在现代操作系统(如Windows、UNIX等)中,进程(Process)和线程(Thread)是两个非常重要的概念,它们对于理解和设计多任务操作系统及其应用程序至关重要。进程...
2. **线程**:线程是进程中的一个执行单元,同一进程中的多个线程共享相同的地址空间和资源,这使得线程间的通信比进程间通信更高效。 3. **`proc_open` 函数**:`proc_open` 是 PHP 中用于创建新进程的一个函数,它...
进程线程 进程线程
- 通过创建多个进程和线程,形成了一个树状结构,其中1号进程为根节点,2号和3号进程为其子节点,2号进程下的线程以及3号进程下的子进程为叶子节点。 - **线程的生命周期**: - 线程从创建到终止的整个过程称为...
一个进程可以拥有多个线程,这些线程共享该进程的资源,如内存空间等。 #### 三、进程与线程的区别 1. **资源占用**: - **进程**:每个进程都有自己独立的地址空间和其他资源,因此创建和销毁一个进程的开销较大...
点击进程,可以在下方看到该进程的线程列表,以及每个线程的ID、状态和CPU使用情况。 2. **性能监视器**:通过`Perfmon.exe`(性能监视器),我们可以获取更详细的性能数据。在“性能监视器”中,添加数据收集器集...
在操作系统课程设计中,Linux进程与线程的通信是一个核心且复杂的主题。在这个项目中,学生将深入理解操作系统内核如何管理和协调不同进程和线程之间的数据交换,从而实现高效的任务执行。以下是对这个主题的详细...
服务器客户端-socket(进程线程),包括套接字,多线程,多进程,单进程,并发,互斥锁,tcp/ip,udp等
在安卓开发中,进程和线程的管理是优化应用程序性能的关键环节。特别是在处理密集型计算或者需要高效利用硬件资源的任务时,将特定的线程或进程绑定到特定的CPU核心上,可以有效提升效率,减少上下文切换带来的开销...
### UNIX线程和轻量级进程 #### 一、引言与背景 在传统的UNIX系统中,进程模型存在两个主要的局限性:一是对于需要并发执行独立任务的应用程序而言,进程模型强制这些任务进行串行化处理或者采用低效的方式来管理...
当一个线程试图获得已持有的互斥量时,该线程会被挂起,直到拥有互斥量的线程释放它。Mutex类提供了CreateMutex、ReleaseMutex等函数,用于创建、控制和释放互斥量。 四、临界区 临界区是最简单的线程同步机制,它...
### 进程线程及堆栈关系的总结 #### 一、进程与线程的概念及其关系 **进程**是具有一定独立功能的程序在一个特定数据集合上的运行活动,是系统进行资源分配和调度的一个独立单位。进程是操作系统进行管理和调度的...
Java 第二阶段提升编程能力【线程(基础)】---- 代码 Java 第二阶段提升编程能力【线程(基础)】---- 代码 Java 第二阶段提升编程能力【线程(基础)】---- 代码 Java 第二阶段提升编程能力【线程(基础)】---- ...
### 操作系统中进程与线程的创建及线程模型 #### 1. 为什么引入线程? 在深入了解为何引入线程之前,我们先明确几个基本概念:程序、进程和线程。 - **程序**:是指为了完成特定任务而编写的一系列有序指令,通常...