什么是进程、什么是线程。
进程(Process):是操作系统中要完成某种功能的一次运行活动。
线程(Thread): a、线程也被称为轻量级进程、是cqu调度的基本单位,
b、一个线程只能属于一个进程、一个进程可以包含多 个线程。在同一个进程中、所有线程都共享进程的 内存地址空间、因此线程能访问相同的变量并在同一个堆上分配内存对象。由于此特性、在同一进程下 面,多个线程访问共享数据的时候需要进行适当的数据共享机制、否则会产生不可预测的后果。
使用线程的优势
1、提高CPU利用率、提高吞吐量。
假设现在有一台计算机包含4个处理器、如果串行的执行某个任务(只有一个线程),那么该线程最多只能在一个cpu上执行(线程是CPU调度的最小单位),那么整个CPU资源有75%无法使用。还有、当同步等待某个I/O操作完成时、CPU也是出于空闲状态的。然而使用多线程、我们可以充分利用多处理器的强大威力、使CPU尽可能的多处理忙碌状态、从而提高CPU利用率。在等待某个I/O操作完成的时候、使用多线程、也提高了单个CPU的吞吐率(CPU可以选择在I/O操作还没有完成的时候去处理其他事情)。
2、提高用户的响应速度
考虑上面提到的串行等待某个I/O操作完成的场景、如果I/O还没有完成的时候、又有一个请求需要处理、那么新的请求只能等到I/O操作完成的时候才能开始处理。其实在开发桌面应用程序的时候、如winform,有一条开发准则是不允许在UI线程中执行复杂的数据处理逻辑,目的就是为了提升响应速度、提升用户体验(想想如果点击一个按钮,界面一致处于未响应状态、什么都不能做、是不是很抓狂,但是点击按钮以后、你还可以操作界面其他控件,那么你的体验就会不一样)。
3、利于程序建模
通常在一个应用程序、需要完成不同类型的任务,比如读取某个文件中的内容、访问数据库、在程序执行的各个阶段打印日志等等。使用多线程、我们可以将这些不同类型的任务分离出来,比如单独创建一个打印日志的程序、那么我们只需要在程序执行的某个阶段、通过某种方式告诉日志线程打印日志即可,而不需要在程序的每个需要打印日志的地方去实现打印日志的逻辑。
使用线程的风险
1、安全性问题
在谈到线程特性b的时候,我们说一个进程下多个线程可以访问进程的共享变量,而线程的交替执行时不可徐预测的。如果某个线程访问了共享变量,在没有采取额外措施且该操作是非原子操作的情况下,那么可能会出现安全性问题。比如当先线程A读取的数据是失效的,比如一个线程读取了一个共享状态变量flg,但是此时,另外一个线程B修改了这个flg,那么对线程A来说,读取flg的值是失效的、那么线程A接下来的处理逻辑也将会是错误的。 线程的安全是不允许破坏的、因为程序都执行错误了,那么这个程序还有什么意义呢。
2、程序活跃性问题
一个并发应用程序能及时执行的能力称为活跃性。常见的程序活跃性问题有:死锁、活锁、线程饥饿。其中死锁和活锁会导致程序无限循环执行、而线程饥饿会导致某个线程很久都得不到处理。这些问题的产生不总是能够重现。
3、性能问题
创建多线程和cpu线程调度都需要消耗一定的资源,而多线程也不是一定能提高cpu的资源利用率。当使用多线程消耗的成本大于多线程提高cpu资源利用的价值的时候、我们才能说使用多线程是有价值意义的。