进程线程
在开发中,很多时候我们都会说到多任务处理,包括CPU密集型、I/O密集型,而Python比较特殊,我们之前除了进程和线程,还使用了协程,但是对于大多数的语言来说,进程和线程就够用了(毕竟不是每种语言都有GIL全局解释器锁)。
进程
系统中的一个基本概念,它包含着一个运行程序所需要的资源。
一个正在运行的应用程序在操作系统中被视为一个进程,进程可以包括一个或多个线程。
线程
是进程中的基本执行单元,是操作系统分配CPU时间的基本单位。
一个进程可以包含若干个线程,在进程入口执行的第一个线程被视为这个进程的主线程。
区别:
- 简而言之,一个程序至少有一个进程,一个进程至少有一个线程;
- 线程的划分尺度小于进程,使得多线程程序的并发性高;
- 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率;
- 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口;
- 但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制;
- 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。
同步异步
同步
所谓同步,就是发出一个功能调用时,在没有得到结果之前,该调用就不返回或继续执行后续操作。
简单来说,同步就是
必须一件一件事做,等前一件做完了才能做下一件事
。
例如:B/S模式中的表单提交,具体过程是:
- 客户端提交请求
- 等待服务器处理
- 处理完毕返回
在这个过程中客户端(浏览器)不能做其他事
。
异步
异步与同步相对,当一个异步过程调用发出后,调用者在没有得到结果之前,就可以继续执行后续操作。
当这个调用完成后,一般通过状态、通知和回调来通知调用者。
对于异步调用,调用的返回并不受调用者控制
。
对于通知调用者的三种方式,具体如下:
- 状态:即监听被调用者的状态(轮询),调用者需要每隔一定时间检查一次,效率会很低。
- 通知:当被调用者执行完成后,发出通知告知调用者,无需消耗太多性能。
- 回调:与通知类似,当被调用者执行完成后,会调用调用者提供的回调函数。
例如:B/S模式中的ajax请求,具体过程是:
- 客户端发出ajax请求
- 服务端处理
- 处理完毕执行客户端回调,在
客户端(浏览器)发出请求后,仍然可以做其他的事
。
区别:
请求发出后,是否需要等待结果,才能继续执行其他操作。
阻塞非阻塞
阻塞和非阻塞这两个概念与程序(线程)等待消息通知(无所谓同步或者异步)时的状态有关。
也就是说阻塞与非阻塞主要是
程序(线程)等待消息通知时的状态
角度来说的。
- 阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态。
- 阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
- 非阻塞调用指在不能立刻得到结果之前,
该调用不会阻塞当前线程
。
并行并发
并发
在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。。这种方式我们称之为并发(Concurrent)。
并行
当系统有一个以上CPU时,则线程的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)
区别:
- 你吃饭吃到一半,电话来了,你一直到吃完了以后才去接,这就说明你不支持并发也不支持并行。
- 你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并发。
- 你吃饭吃到一半,电话来了,你一边打电话一边吃饭,这说明你支持并行。
并发的关键是你有处理多个任务的能力,不一定要同时。并行的关键是你有同时处理多个任务的能力。
所以它们最关键的点就是:是否是
同时
。
评论区