进程(Process):javascript
是Windows系统中的一个基本概念,它包含着一个运行程序所须要的资源。一个正在运行的应用程序在操做系统中被视为一个进程,进程能够包括一个或多个线程。线程是操做系统分配处理器时间的基本单元,在进程中能够有多个线程同时执行代码。进程之间是相对独立的,一个进程没法访问另外一个进程的数据(除非利用分布式计算方式),一个进程运行的失败也不会影响其余进程的运行,Windows系统就是利用进程把工做划分为多个独立的区域的。进程能够理解为一个程序的基本边界。是应用程序的一个运行例程,是应用程序的一次动态执行过程。php
线程(Thread):html
是进程中的基本执行单元,是操做系统分配CPU时间的基本单位,一个进程能够包含若干个线程,在进程入口执行的第一个线程被视为这个进程的主线程。在.NET应用程序中,都是以Main()方法做为入口的,当调用此方法时系统就会自动建立一个主线程。线程主要是由CPU寄存器、调用栈和线程本地存储器(Thread Local Storage,TLS)组成的。CPU寄存器主要记录当前所执行线程的状态,调用栈主要用于维护线程所调用到的内存与数据,TLS主要用于存放线程的状态信息。java
进程和线程的区别node
进程和线程的主要差异在于它们是不一样的操做系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不一样执行路径。线程有本身的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,因此多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行而且又要共享某些变量的并发操做,只能用线程,不能用进程。ajax
1) 简而言之,一个程序至少有一个进程,一个进程至少有一个线程.apache
2) 线程的划分尺度小于进程,使得多线程程序的并发性高。编程
3) 另外,进程在执行过程当中拥有独立的内存单元,而多个线程共享内存,从而极大地提升了程序的运行效率。浏览器
4) 线程在执行过程当中与进程仍是有区别的。每一个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。可是线程不可以独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。服务器
5) 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分能够同时执行。但操做系统并无将多个线程看作多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。
同步:
所谓同步,就是发出一个功能调用时,在没有获得结果以前,该调用就不返回或继续执行后续操做。
简单来讲,同步就是必须一件一件事作,等前一件作完了才能作下一件事。
例如:B/S模式中的表单提交,具体过程是:客户端提交请求->等待服务器处理->处理完毕返回,在这个过程当中客户端(浏览器)不能作其余事。
异步:
异步与同步相对,当一个异步过程调用发出后,调用者在没有获得结果以前,就能够继续执行后续操做。当这个调用完成后,通常经过状态、通知和回调来通知调用者。对于异步调用,调用的返回并不受调用者控制。
对于通知调用者的三种方式,具体以下:
状态
即监听被调用者的状态(轮询),调用者须要每隔必定时间检查一次,效率会很低。
通知
当被调用者执行完成后,发出通知告知调用者,无需消耗太多性能。
回调
与通知相似,当被调用者执行完成后,会调用调用者提供的回调函数。
例如:B/S模式中的ajax请求,具体过程是:客户端发出ajax请求->服务端处理->处理完毕执行客户端回调,在客户端(浏览器)发出请求后,仍然能够作其余的事。
同步和异步的区别:
总结来讲,同步和异步的区别:请求发出后,是否须要等待结果,才能继续执行其余操做。
阻塞和非阻塞这两个概念与程序(线程)等待消息通知(无所谓同步或者异步)时的状态有关。也就是说阻塞与非阻塞主要是程序(线程)等待消息通知时的状态角度来讲的。
阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.
阻塞调用是指调用结果返回以前,当前线程会被挂起。调用线程只有在获得结果以后才会返回。
非阻塞调用指在不能马上获得结果以前,该调用不会阻塞当前线程。
并发:在操做系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。当有多个线程在操做时,若是系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分红若干个时间段,再将时间 段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。.这种方式咱们称之为并发(Concurrent)。
并行:当系统有一个以上CPU时,则线程的操做有可能非并发。当一个CPU执行一个线程时,另外一个CPU能够执行另外一个线程,两个线程互不抢占CPU资源,能够同时进行,这种方式咱们称之为并行(Parallel)
并发和并行的区别:
你吃饭吃到一半,电话来了,你一直到吃完了之后才去接,这就说明你不支持并发也不支持并行。
你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并发。
你吃饭吃到一半,电话来了,你一边打电话一边吃饭,这说明你支持并行。
并发的关键是你有处理多个任务的能力,不必定要同时。并行的关键是你有同时处理多个任务的能力。
因此我认为它们最关键的点就是:是不是『同时』。
其实,异步是目的,而多线程是实现这个目的的方法。异步是说,A发起一个操做后(通常都是比较耗时的操做,若是不耗时的操做就没有必要异步了),能够继续自顾自的处理它本身的事儿,不用干等着这个耗时操做返回。
多线程和异步操做二者均可以达到避免调用线程阻塞的目的,从而提升软件的可响应性。甚至有些时候咱们就认为多线程和异步操做是等同的概念。可是,多线程和异步操做仍是有一些区别的。而这些区别形成了使用多线程和异步操做的时机的区别。
全部的程序最终都会由计算机硬件来执行,因此为了更好的理解异步操做的本质,咱们有必要了解一下它的硬件基础。 熟悉电脑硬件的朋友确定对DMA这个词不陌生,硬盘、光驱的技术规格中都有明确DMA的模式指标,其实网卡、声卡、显卡也是有DMA功能的。DMA就是直 接内存访问的意思,也就是说,拥有DMA功能的硬件在和内存进行数据交换的时候能够不消耗CPU资源。只要CPU在发起数据传输时发送一个指令,硬件就开 始本身和内存交换数据,在传输完成以后硬件会触发一个中断来通知操做完成。这些无须消耗CPU时间的I/O操做正是异步操做的硬件基础。因此即便在DOS 这样的单进程(并且无线程概念)系统中也一样能够发起异步的DMA操做。
线程不是一个计算机硬件的功能,而是操做系统提供的一种逻辑功能,线程本质上是进程中一段并发运行的代码,因此线程须要操做系统投入CPU资源来运行和调度。
由于异步操做无须额外的线程负担,而且使用回调的方式进行处理,在设计良好的状况下,处理函数能够没必要使用共享变量(即便没法彻底不用,最起码能够减小 共享变量的数量),减小了死锁的可能。固然异步操做也并不是完美无暇。编写异步操做的复杂程度较高,程序主要使用回调方式进行处理,与普通人的思惟方式有些 初入,并且难以调试。
多线程的优势很明显,线程中的处理程序依然是顺序执行,符合普通人的思惟习惯,因此编程简单。可是多线程的缺点也一样明显,线程的使用(滥用)会给系统带来上下文切换的额外负担。而且线程间的共享变量可能形成死锁的出现。
异步与多线程,从辩证关系上来看,异步和多线程并不时一个同等关系,异步是目的,多线程只是咱们实现异步的一个手段.什么是异步:异步是当一个调用请求发送给被调用者,而调用者不用等待其结果的返回.实现异步能够采用多线程技术或则交给另外的进程来处理
非专业人员,就用非专业的语言解释下吧,比喻不够贴切,但大概是那么个意思,
先听我讲一个故事:
那仍是10年前,尚未12306的年代,你们买票只能去火车站买。由于你们都要过年回家,都还不想等,火车站只有一个,窗口只有那么多,头疼啊。更头疼的是,排到窗口的那我的,各类挑剔,不要贵的,不要晚上的,不要站票......跟售票员各类墨迹,后面的人更加着急,一个个义愤填膺,骂爹骂娘。
如今假设整个城市就只有1个火车,1个售票员,每一个乘客咨询售票员后须要思考1分钟再决定买哪趟车的票。
1.异步:在买票的人咨询后,须要思考1分钟,立刻靠边站,但不用从新排队,何时想清楚能够立马去跟售票员去买票。在该人站在旁边思考的时候,后面的人赶忙上去接着买。这时候队伍是很快的挪动的,没有阻塞,售票员的最大化的效率。
2.多线程:火车站开n个窗口(但仍是只有一我的售票),外面同时排n个队,售票员回答咨询者问题后,立马立刻去下个窗口,而后继续轮换到下个窗口.....哪一个窗口的人决定好了,售票员立马过去买给他。这个时候乘客比较简单,但万一那个队伍有人思考半天纠结,后面的人就悲剧了。
3.并行:复制n个火车站,同时卖票,买票能力大大加强。你们也能够哪一个火车站人少,就去那个买票。
可见:在只有一个火车站,且只有一个售票员的状况下,卖完一个再卖一个就会致使资源浪费,效率低下,队伍卡死,很难往前挪动。1,2优化的办法都解决了队伍不动,售票率低下的问题。但增长火车站,增长窗口,增长售票员才是好办法。
结论:
1.异步和多线程其实效率差很少,可是开的窗口很少例如3个,同时有不少人都是去花5分钟,而不是1分钟去纠结的时候,多线程效率实际是低于异步的,由于售票员仍是常遇到3个队伍同时卡在那纠结不能买票的时候。
2.这2个概念拿来对比也有点不合适,由于他们不是一个概念,多线程的目的仍是为了实现异步,多线程应该是一种实现异步的手段。异步应该去跟同步比较才对。
3.多线程比较简单,但须要增设窗口,增长成本,且售票员比较累这相似apache下php,和node.js下javascript的关系,一个是多线程,可是是阻塞的,另一个是单线程异步非阻塞的。php的方案比较符合常规思惟,但比较费内存,node.js非阻塞,用较少的资源就能完成一样的任务,但编程比较费神。
4.并行,相似同时利用多核cpu的各个核去计算。并发可分为伪并发、真并发。前者例如单核处理器的并发,后者发是指多核处理器的并发。
5.终极办法是并行计算,而且每一个cpu下进行异步计算,这样你的每一个核都充分利用。只不过对编程要求过高了过高了,若是不是密集型计算,例如大型有限元计算(多采用并发),或者服务器同时处理上千的访问(多采用异步或者多线程),仍是老老实实的用传统的办法吧,毕竟常规程序的计算量对如今的硬件来讲,问题都不大。
理解同步阻塞、同步非阻塞、异步阻塞、异步阻塞、异步非阻塞
同步/异步关注的是消息通知的机制,而阻塞/非阻塞关注的是程序(线程)等待消息通知时的状态。
以小明下载文件打个比方,从这两个关注点来再次说明这两组概念,但愿可以更好的促进你们的理解。
同步阻塞:小明一直盯着下载进度条,到 100% 的时候就完成。
同步体如今:等待下载完成通知;
阻塞体如今:等待下载完成通知过程当中,不能作其余任务处理;
同步非阻塞:小明提交下载任务后就去干别的,每过一段时间就去瞄一眼进度条,看到 100% 就完成。
同步体如今:等待下载完成通知,可是要在;
非阻塞体如今:等待下载完成通知过程当中,去干别的任务了,只是时不时会瞄一眼进度条;【小明必需要在两个任务间切换,关注下载进度】
异步阻塞:小明换了个有下载完成通知功能的软件,下载完成就“叮”一声。不太小明仍然一直等待“叮”的声音(看起来很傻,不是吗)。
异步体如今:下载完成“叮”一声通知;
阻塞体如今:等待下载完成“叮”一声通知过程当中,不能作其余任务处理;
异步非阻塞:仍然是那个会“叮”一声的下载软件,小明提交下载任务后就去干别的,听到“叮”的一声就知道完成了。
异步体如今:下载完成“叮”一声通知;
非阻塞体如今:等待下载完成“叮”一声通知过程当中,去干别的任务了,只须要接收“叮”声通知便可;【软件处理下载任务,小明处理其余任务,不需关注进度,只需接收软件“叮”声通知,便可】
也就是说,同步/异步是“下载完成消息”通知的方式(机制),而阻塞/非阻塞则是在等待“下载完成消息”通知过程当中的状态(能不能干其余任务),在不一样的场景下,同步/异步、阻塞/非阻塞的四种组合都有应用。
因此,综上所述,同步和异步仅仅是关注的消息如何通知的机制,而阻塞与非阻塞关注的是等待消息通知时的状态。也就是说,同步的状况下,是由处理消息者本身去等待消息是否被触发,而异步的状况下是由触发机制来通知处理消息者,因此在异步机制中,处理消息者和触发机制之间就须要一个链接的桥梁:
在小明的例子中,这个桥梁就是软件“叮”的声音。
同步/异步与阻塞/非阻塞#
1 同步阻塞形式
效率是最低的,
拿上面的例子来讲,就是你专心等待下载完成,什么别的事都不作。
实际程序中:就是未对fd 设置O_NONBLOCK标志位的read/write 操做;
2 异步阻塞形式
异步操做是能够被阻塞住的,只不过它不是在处理消息时阻塞,而是在等待消息通知时被阻塞。
好比select 函数,假如传入的最后一个timeout参数为NULL,那么若是所关注的事件没有一个被触发,程序就会一直阻塞在这个select 调用处。
3 同步非阻塞形式
其实是效率低下的,
想象一下你一边干别的事情一边还须要抬头看下载完成没有,若是把干别的事情和观察下载完成状况的位置当作是程序的两个操做的话,这个程序须要在这两种不一样的行为之间来回的切换,效率可想而知是低下的。
不少人会写阻塞的read/write 操做,可是别忘了能够对fd设置O_NONBLOCK 标志位,这样就能够将同步操做变成非阻塞的了。
4 异步非阻塞形式
效率更高,
由于等待下载完成是你(等待者)的事情,而通知你则是电脑(消息触发机制)的事情,程序没有在两种不一样的操做中来回切换。
至此,关于进程线程、同步异步、阻塞非阻塞、并发并行已经讲的差很少了,有讲的很差的地方请大佬指出。同时也谢谢网上大佬的文章帮助我理解了这些概念。
参考链接:
https://www.zhihu.com/question/33515481/answer/58849148
https://www.cnblogs.com/dream844/archive/2012/06/12/2546083.html
https://www.jianshu.com/p/aed6067eeac9
https://www.zhihu.com/question/28550867/answer/55357128