【ca888会员登录】操作系统与程序运维以及经过简

2019-03-30 12:38栏目:编程程序

二.进程与线程

进程 进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会创建一个进程,系统会给每个进程分配独立的内存地址空间,并且每个进程的地址不会相互干扰。如果要完成CPU时间片的切换,就要保证之前的进程在执行的时候执行到某个位置,下次切换回来的时候仍然可以从这个位置开始执行。所以进程就是资源分配的最小单元。 在进程出现之前,指令是一次性加载到内存中,如果要进行指令切换的话,就要对指令进行隔离,而在批处理操作系统中是无法对指令进行隔离的。 有了进程以后,可以让操作系统从宏观上实现并发。并发是通过CPU时间片的不断切换执行的。在任意一个时刻,对于单核CPU来说,只会有一个任务去执行,只是通过切换时间片的方式完成了并行执行。 线程 线程是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,每个线程会负责一个独立的子任务,在配合多核处理器,去实现多个子任务并行处理的结果。线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。线程由CPU独立调度执行,在多核CPU环境下就允许多个线程同时运行。进程在一个时间内只能干一件事情,如果想同时干多件事情的话, 就要把进程中的多个子任务划分到多个线程,通过线程的切换执行去实现任务的实时性。所以,线程是真正意义上实现了并行执行。

批处理操作系统虽然能够解决计算机的空闲问题,但是当某一个作业因为等待磁盘或者其他I/O操作而暂停,那CPU就只能阻塞直到该I/O完成,对于CPU操作密集型的程序,I/O操作相对较少,因此浪费的时间也很少。但是对于I/O操作较多的场景来说,CPU的资源是属于严重浪费的。

线程的出现,在多核心CPU架构下实现了真正意义上的并行执行。也就是说,一个进程内多个任务可以通过多线程并行执行来提高程序运行的性能。那线程的使用场景有哪些呢?

线程与操作系统

操作系统是对计算机硬件资源的管理程序,是应用程序与计算机硬件交互的中间层,其本质仍旧是运行于硬件电路上的程序对计算机硬件来说不存在操作系统,只是处理器对指令的执行,不过操作系统是一个特殊一点的程序。ca888会员登录 1而对于应用开发者来说,以JavaWeb为例,我们却接触了太多的东西,首先是Java语言本身,然后........... servlet?jsp?MVC?Spring?SpringBoot?ORM?Mybatis?Dubbo? 然而,这些其实仍旧还是Java本身--Java语言编写的程序,纵然有那么多的规范,协议,他也只是一个Java编写的程序 所以不管你用了多少技术,框架,模式,实现了怎么样的协议与功能,原理是什么,也只是人类意识层面上的内容,到底层只有指令。 用到的一些应用软件,MYSQL?REDIS?也只是程序。 所以,运行于计算机之上的这一切都只是程序这些程序经过指定的步骤,从高级到低级,从人类可以理解到无法识别,最终转换为计算机可以识别的指令。 ca888会员登录 2我们编写的所有的源代码,最终都要转换成计算机系统可以识别的内容,而计算机系统包括硬件以及运行其上的系统软件。**我们所有的编码,都是面向指定的语法,而这门语言本身,则是面向操作系统的,因为外部软件通常是不能直接操纵硬件资源,需要借助于操作系统。所以某种程度上可以这样认为,所有的源代码都是面向语言的,而语言本身面向操作系统。ca888会员登录 3操作系统提供了对于计算机硬件资源的管理,对于这些资源的访问,提供了一系列的方法途径,这些途径方法如同机器的操作面板,如同驾驶舱的按钮手柄。 所以说,计算机有什么不重要,计算机操作系统有什么才重要。最简单的例子就是重装系统后,如果没有网卡驱动,你的电脑将无法了解Internet,尽管你的网卡就好端端的插在哪里。对绝大多数应用程序员来说,操作系统,便是神一样的存在,所有的一切都要仰仗于他。**

一.多线程的发展历史

异步处理,比如在用户注册成功以后给用户发送优惠券或者短信,可以通过异步的方式来执行,一方面提升主程序的执行性能;另一方面可以解耦核心功能,防止非核心功能对核心功能造成影响

了解进程、线程模型

什么是程序?

遵循某种语言的源代码经过编译、翻译等步骤转换后的一组计算机能识别和执行的指令,这就是程序。 这是一种静态的资源,当你的电脑中安装一个软件后,如果不启动软件,该软件仅仅是占用磁盘空间 一个程序就像一个用汉字写下的红烧肉菜谱,用于指导懂汉语和烹饪手法的人来做这个菜。菜谱就是存在于纸上的文字。 当程序需要运行时,操作系统会加载该程序的信息到内存中,并且分配CPU时间片以及其他硬件硬件资源,并且会对这些资源进行管理,比如数据加载到内存的什么位置了? 而且,现代操作系统都可以同时并发执行多个程序,内存中的这些数据又都是哪个程序的?某个软件在进行切换时执行到哪里了?等等这些都需要操作系统进行管理操作系统将程序的一次运行抽象为进程**简言之,如果 你按照 菜谱去 做菜,这个过程就叫做 下厨做饭**ca888会员登录 4抽象的概念,没有人会陌生,如果我们想使用Java语言描述一个学生,我们可能会创建一个Student类,里面有各种属性,比如姓名、年龄等

public class Student {private Long id;// idprivate String name;// 姓名private Integer age;// 年龄private String sex;// 性别  //.............等等

这样一个Class就是一个数据结构,通过他对学生进行描述而进程是操作系统对程序的一次执行的抽象,也就是说一个程序运行需要哪些信息、数据?这些所有的数据项集合就叫做进程。简言之就是一个程序运行所需信息的描述集合。我们以类来比喻的话可能是这样子:

public class 进程 {private Long 进程号;private String 程序计数器PC;private String xxx寄存器;private String 堆栈内容;// ............................等等}

还有一个概念是进程上下文,刚才说到现代系统还可以并发的执行多道程序,必然存在着CPU的切换,那么从一个程序切换到另一个程序时,如何才能够恢复?既然进程是程序的一次运行过程中所需要信息的集合,如果在切换时,将这一瞬时状态,这一集合体各项数据记录下来,当再次切换回来时,只需要将数据恢复不就好了吗进程执行活动全过程的这一个静态描述叫做进程上下文进程间的切换,也被称之为上下文切换。**通俗比喻:**如果只有一个厨房,你做菜做一半了,然后需要让出来厨房让别人做,你需要做什么?收拾好你的食材,记住你刚才食材放置的位置以及处理的进度,哪个菜洗过了?盐放过了么?。。。等等这些数据就是进程上下文,当别人撤出去之后,你需要将这些状态还原,这就是上下文切换。随着现代计算机技术的发展,进程的弊端开始出现,由于进程是资源拥有者,创建、撤消与切换存在较大的时空开销,因此需要引入轻型进程,线程就是轻量级的进程。 进程仍然是资源分配的基本单位,线程是程序执行的最小单位 线程的出现可以理解为计算机操作系统对于程序的执行进行了更加精细化的控制,将资源分配,程序运行进行了更加细致的分工。 每个线程都运行在进程的上下文中,共享同样的代码和全局数据,很显然,多线程比多进程更容易共享数据。 总之,线程的出现是操作系统技术的发展,为了更加细化分工,节省开销的一种做法,是在进程的基础上发展而来的。

欢迎加群 499754614学习交流,备注豆瓜。

内容导航

  • 真空管和穿孔卡片
  • 晶体管和批处理系统
  • 集成电路和多道程序设计

总结

不管是进程还是线程,都是操作系统对于程序执行的抽象描述,是相关数据:寄存器状态、堆栈值等所有相关数据的集合。 通过进程的相关信息的维护管理,操作系统保障多道程序可以顺利的切换执行; 而对于多线程的应用程序,需要开发者对线程的数据等相关信息进行控制,以保证多线程间可以正确的运行。 多线程共享进程资源,而有些资源是互斥的,并不能允许同时访问,比如对计数器 1,如果临界区代码可以同时访问,可能两个人同时过来,每个人同时从1开始执行加1操作,结果却是2,这显然是不正确的 多线程编程需要解决的核心就是互斥资源的访问以及如何高效的利用CPU。 保障资源的互斥访问是为了保证程序的正确性,否则再快的程序也没有意义;如果编写的程序非常的不合理,逻辑不清晰,反而可能会带来性能问题,而不是提高效率。 所以多线程相关的技术的确很复杂,而且非常容易出错,而且学习成本很高,但是,他终归是为了提高CPU的利用率的同时并且保障临界资源的正确访问。 作为多线程编程人员,如同交警,你需要合理的指挥,提高路口的通行效率,尽最大可能缓解交通堵塞情况,而且需要保证不能在你的指挥下还发生了交通事故或者造成了更大的拥堵; 这是两个主要方面,就是前面提到的效率和互斥访问。 另外路口我应该清场出来多大空间用来调度指挥?过几分钟这个方向的走,过几分钟那个方向的走?我是轮流几秒钟切换下?还是哪边车多让哪边多走一会还是怎么样?这些细节非常复杂繁琐。 在未来的一段时间内,多线程编程模型是必然的趋势,也是程序员必须要面对的一件事情,过去的单处理器系统,并发可能是多余的,但是今天,已经成为了势不可挡的趋势。 随着技术的发展,多线程的开发也在从复杂往简单的方向演化(尽管现在仍旧看起来很复杂),随后可能会慢慢地出现很多集成、封装、框架等以让多线程编程更加简单 就如同EJB-Spring-SpringBoot的发展,企业级应用的开发过程一直在简化,但是核心原理却不断的被封装在深处,如果不了解底层,只会招式,永远也打不出来有力的拳头,所以建议大家尽可能的深入学习多线程 本系列文章作为自己的学习记录,从操作系统中关于进程线程并发的相关概念切入,开始介绍Java多线程编程。 原文地址:操作系统与程序运行以及进程简介 多线程上篇

三.多线程的使用场景

因为多线程最终解决的是“等待”的问题,所以多线程一般用于: 1.通过并行计算提高程序执行的性能,比如一个程序中的计算逻辑的执行性能可以通过多线程的技术将一个程序中的多个逻辑运算并行操作执行。 2.需要等待网络,IO响应等耗费大量的时间,可以采用异步的方式来减少总体的响应时间,也就是解决阻塞(当程序运行到某个函数时,由于一些原因导致程序要等待某个事件的发生而暂时停止占用CPU)的问题,阻塞会使CPU闲置而浪费资源。

线程的应用场景

ca888会员登录 5

多线程

很久很久很久以前,操作系统以串行的方式运行,当正在执行的程序遇到阻塞操作,比如等待IO时,CPU空闲等待,极大地浪费了CPU 所以后来出现了多任务操作系统,可以对程序进行切换,当遇到阻塞操作时,CPU可以去执行另外的程序,提高了CPU的利用率 对于线程也是如此,多线程技术相当于是应用程序内部的“多任务”。就好比一个应用程序内部有多个线程,其中一个线程等待IO操作时,可以切换执行其他的线程,完成其他的任务,所以对于多线程编写的程序,看起来程序能够更快的完成。 所以刚才说线程是操作系统对于程序运行过程的更加细致的划分与掌控,对于一个多线程程序,能够更加充分的利用CPU资源,看起来执行快了,是因为CPU的效率变高了,而不是程序的运行所需时间变少了 对于一个单CPU系统,对于多任务的实现就是并发,操作系统不断地进行着切换,将时间片分配给不同的程序,以看起来像多个程序是共同运行的。 通过多线程,将一个应用程序本身拆解为多任务,如果像上面说的某个线程等待IO导致阻塞,可以执行其他的线程任务,那么将会提高CPU的利用率 但是如果是类似1 2 3 4...... N的计算呢?假设计算过程是均等的,这不会出现IO阻塞的情况,每一次的运算都是相同的,CPU本身也没有空闲等待的浪费,所以CPU利用率没有上升,相反还会有线程切换维护的开销,所以整体看性能或许略有下降。 所以说,单核场景下,尽管多线程在有些场景下可以提高CPU的利用率,但是对于单CPU系统系统,在有些场景下,反而会降低整体性能。因为有的时候你并不能提高利用率;而且有的时候即使提高了利用率,如果提高的那一部分利用率,还不足以抵消做的那些不该做的事情的开销,整体看并不一定是往好的方向发展。 很显然,对于单CPU尽管有些场景多线程可以提高利用率,但是有时也并不能,所以多线程编程并没有强势发展。但是后来,CPU主频的发展越来越缓慢,对于CPU主频的升级,摩尔定律开始失效了,因为发展太快,集成电路越来越接近极限了。 既然纵向不能发展,人们总是有办法的,开始横向发展,不再追究单核的计算速度,而是研究如何能够将多个独立的计算单元整合到一个CPU中,也就是现在说的多核。 随着技术的发展, 能够装载的核心数目越来越多 对于多核CPU,能够真正的做到在同一瞬时,执行多个线程,是真正的并行。 所以很显然,这种场景对于真正的并行,不管你的程序任务是什么样子的,对于多线程程序,必然能够提高程序的执行速度。 如果只要一个老师辅导三个学生,你需要合理的安排时间任务,才有可能提高整体的效率;但是如果三个学生对应着三个老师同时在辅导,整体的效率肯定是提高的。 所以随着多核CPU以及超线程技术的发展,多线程编程就显得格外重要。 如果单核CPU的性能可以无限制的快速提高,软件开发者完全不用关心多线程编程,一切交给CPU就好了 但是,目前的情况却是CPU的性能已经达到瓶颈,硬件在横向发展,所以如果想要提高CPU的利用率,让你的程序更快的执行,你将不得不面对多线程编程。 《实战Java高并发程序设计》中提到:“顶级计算机科学家唐纳德·尔文·克努斯(Donald Ervin Knuth ),如此评价这种情况: 在我看来,这种现象或多或少是由于硬件设计者己经无计可施了导致的,他们将摩尔定律失效的责任推脱给软件开发者。” 也说明了这个问题----现在为什么要更加关注多线程技术?多核场景以及超线程技术的发展下,不是你主动地想要去使用多线程技术,而是现有的硬件体系,想要获得更好地程序性能,你将不得不使用多线程技术进行编程。 当我处理器还是只能一个一个的来的时候,你们是不是多线程并没有那么重要 但是当我可以瞬时同时处理多个线程的时候,如果你还是只有一个线程,你每一时刻也只会有一个线程在执行,但是别人-多线程程序,可能就是多个,所以你的程序的速度与别人相比怎么样? 尽管借助于多线程技术,因为有线程切换等系统开销,所以总共需要CPU做的事情,要大于单线程的时候; 但是CPU多核的并行处理能力以及CPU利用率的提高,将会大大的提高程序的整体效率 所以在多核时代,多线程是必须要考虑的问题。

多线程的发展大约经过了三个历史阶段: 1.最早出现的计算机主要是为了解决复杂的计算问题,而早期的计算机只能够接受一些特定的指令,当用户在输入这个指令的时候,计算机才会去工作,如果不输入指令,计算机就不会工作,因为计算机本身不会存储指令,很多情况下,计算机都会处于等待状态,并没有真正利用计算机本身的资源。于是进入了批处理操作系统的演变过程。 2.批处理操作系统:用户把需要执行的多个指令写在磁带上,然后让计算机去读取这个磁带执行相应的程序,并把结果输出在另外一个磁带上。 3.虽然批处理这种方式能大大提升计算机资源的利用率,但是会遇到一些问题,比如,操作系统的一个指令阻塞了,CPU会等到这个指令执行完毕后,再去执行下一个指令,这样的话就会使CPU处于等待状态,无法提高资源的利用率。为了解决这个问题,就出现了进程和线程的概念。

WAITING是通过Object.wait或者Thread.join、LockSupport.park等操作实现的

这里有一个问题大家可能搞不明白,BLOCKED和WAITING这两个阻塞有什么区别?

并发与并行

下面这幅图可以很好地解释并发与并行 ca888会员登录 6一个咖啡机两个队伍,就是并发;两个咖啡机,两个队伍,就是并行。 并发 concurrent ,通过CPU调度算法,进行进程间的切换,也就是多任务执行,操作系统将CPU时间片分配给每个进程,给人并行处理的感觉 并行 parallel,并行就是同时执行的意思,多个CPU或者多个机器同时执行一段处理逻辑,是真正的同时。

每次学习一个新技术,我会先去了解这个技术的背景,这个过程看似浪费时间,其实在后续的学习过程中,能够促进理解很多问题。所以对于线程这个概念,我会先从操作系统讲起。因为操作系统的发展带来了软件层面的变革。 从多线程的发展来看,可以操作系统的发展分为三个历史阶段:

  • NEW:初始状态,线程被创建时候的状态,还没有调用start方法
  • RUNNABLE:运行状态,运行状态包含就绪和运行两种状态,因为线程启动以后,并不是立即执行,而是需要通过调度去分配CPU时间片
  • BLOCKED:阻塞状态,当线程去访问一个加锁的方法时,如果已经有其他线程获得锁,那么当前线程会处于阻塞状态
  • WAITING:等待状态,设置线程进入等待状态等待其他线程做一些特定的动作进行触发
  • TIME_WAITING:超时等待状态,和WAITING状态的区别在于超时以后自动返回
  • TERMINATED:终止状态,线程执行完毕

本系列将对Java多线程进行简单的介绍。分为上中下三个章节。 上篇对操作系统中关于进程、并发的相关概念以及问题进行了介绍; 中篇对Java多线程的基础进行介绍; 下篇将会对Java多线程编程提供的工具、模式进行介绍; Java多线程,首先需要了解线程,了解线程又需要对进程有所了解,而了解进程你需要知道程序的概念,知道程序的概念,你还需要了解操作系统。

晶体管和批处理系统

  • BLOCKED状态是指当前线程在等待一个获取锁的操作时的状态。
  • WAITING是通过Object.wait或者Thread.join、LockSupport.park等操作实现的
  • BLOCKED是被动的标记,而WAITING是主动操作
  • 如果说得再深入一点,处于WAITING状态的线程,被唤醒以后,需要进入同步队列去竞争锁操作,而在同步队列中,如果已经有其他线程持有锁,则线程会处于BLOCKED状态。所以可以说BLOCKED状态是处于WAITING状态的线程重新唤醒的必经的状态

线程的生命周期

总的来说,并行是并发的子集。也就是说我们可以写一个拥有多线程并行的程序,如果在没有多核心CPU来执行这些线程,那就不能以并行的方式来运行程序中的多个线程。所以并发程序可以是并行的,也可以不是。Erlang之父Joe Armstrong通过一张图型的方式来解释并发和并行的区别,图片如下

从性能上考虑,如果进程中存在大量的I/O处理,通过多线程能够加快应用程序的执行速度(通过CPU时间片的快速切换)。

前面分析了线程的发展历史,这里简单总结一下线程有的优势如下

ca888会员登录 7

「阿里面试系列」搞懂并发编程,轻松应对80%的面试场景

下图整理了线程的状态变更过程及变更的操作,每一个具体的操作原理,我会在后续的文章中进行详细分析。

下图整理了线程的状态变更过程及变更的操作,每一个具体的操作原理,我会在后续的文章中进行详细分析。

批处理操作系统的运行方式:在输入室收集全部的作业,然后用一台比较便宜的计算机把它们读取到磁带上。然后把磁带输入到计算机,计算机通过读取磁带的指令来进行运算,最后把结果输出磁带上。批处理操作系统的好处在于,计算机会一直处于运算状态,合理的利用了计算机资源。(运行流程如下图所示)

ca888会员登录 8

ca888会员登录 9

最早的计算机只能解决简单的数学运算问题,比如正弦、余弦等。运行方式:程序员首先把程序写到纸上,然后穿孔成卡票,再把卡片盒带入到专门的输入室。输入室会有专门的操作员将卡片的程序输入到计算机上。计算机运行完当前的任务以后,把计算结果从打印机上进行输出,操作员再把打印出来的结果送入到输出室,程序员就可以从输出室取到结果。然后,操作员再继续从已经送入到输入室的卡片盒中读入另一个任务重复上述的步骤。

TIME_WAITING:超时等待状态,和WAITING状态的区别在于超时以后自动返回

ca888会员登录 ,「阿里面试系列」搞懂并发编程,轻松应对80%的面试场景

前面分析了线程的发展历史,这里简单总结一下线程有的优势如下

有了进程以后,为什么还会出现线程呢?

版权声明:本文由ca888发布于编程程序,转载请注明出处:【ca888会员登录】操作系统与程序运维以及经过简