PS:本来想直接上手做个软件,结果发现自己蠢到在主线程里面写了个死循环,才意识到自己必须要了解多线程的知识了,话不多说 ,来看看。
先来捋清一下概念吧
程序是计算机指令的集合,进程是正在运行当中的程序,每一个进程都被定义为一个正在运行程序的实例。
一个程序可以对应多个进程,并且一个进程也可以同时调用多个程序。
进程是计算机中独立运行的单元,系统为他分配资源,调度。
一个进程有两个部分组成,第一个是进程控制块,也就是操作系统用来管理进程的内核对象,它是一个数据结构,里面存满了关于这个进程的一切信息。这个对象只能够被操作系统内部来访问。第二部分,是地址空间,也就是所谓的存放数据和程序代码的内存空间。
进程和线程的关系(对于新手SO重要)
进程其实不执行任何东西,进程相当于一个机器的大箱子外面的那层壳子,他只提供了一个容器的作用。而真正运行代码实现功能的是进程里面的线程。进程只是线程的执行环境。理解了这个基本上,进程和线程是怎么回事就知道了。(话说学操作系统的时候就学过,但是貌似那时候是我忘了还是没听懂,总是对进程和线程分不清)
一个进程可以包含多个线程,一个进程至少包含一个线程。当我们创建一个进程的时候,操作系统会自动为这个进程创建一个线程,这个线程叫I做主线程,是main函数或者winmain函数的线程。这两个函数将会是主线程的接入函数。之后可以在主线程中创建其他子线程。
每一个进程都有自己独立,私有的内存空间,操作系统中说过,每一个进程都是相互独立的,即使他们之间要交流,也是通过进程间的通信来实现的。
每一个进程都有一个地址空间,地址空间说白了也就是寻址范围,也就是内存的范围,一般来说32位的机器都是4GB的寻址范围。我们现在所使用的计算机,当我们打开任务管理器的时候:
在下面会看到一个物理内存,这个物理内存不仅仅是包含我们自己本身给电脑查的内存条的那个容量,在操作系统中还有一个叫做页文件的东西,实际的物理内存的大小等于页文件的大小加上内存条容量的大小。一般学了操作系统的人到这都应该明白了,或者说看过Linux的人更应该清楚,这个页文件实际上就是虚拟内存,利用了磁盘的空间来增加内存的容量。linux中如果实际的硬盘上没有空间继续分区的话,不是也可以创建一个大文件作为分区么,或者是swap这个分区,不也就是为了防止内存不租做虚拟内存来用么,道理应该都是一样的。
关于线程
线程也是由两个部分组成:
线程的内核对象,由操作系统来进行管理,感觉就是线程控制块。
线程栈,和我学汇编的时候看到的函数调用的函数栈差不多,都是用来存储一些函数和局部变量的,属于在内存中给一段自由的空间吧。
线程的建立是在进程的空间中的,系统在进程的内存空间中为线程分配空间。因线程是在进程的内部,所以线程可以访问进程的内核对象,也可以访问这个进程的所有内存空间,以及在这个内存空间创建的其他线程的堆栈,这也是单进程中多线程的通信原理。
一个线程只有一个内核对象和一个栈。
线程的运行
OS会为每一个线程分配一些时间来运行,这也就是学习操作系统时候学过的时间片轮转的进程调度算法。在同一个进程中的不同线程也将会遵循这种时间片轮转的办法来为每一个线程的运行分配时间,为了方式线程(进程)的饿死或者饥饿,在计算机比较NB的情况下,可以尽量缩短时间片的大小,达到人们一种很多线程同时运行的错觉。
多线程的程序中进程的运行效率肯定会比单线程的运行效率要更很多,毕竟是有多个线程同时在运行。但是在单CPU的条件下一次也只能运行一个线程,即使这个进程是多线程的,但是如果搬到多CPU上的机器时,多线程的程序就 可以发挥出他的优点了。
如果你的电脑足够NB,那么你 可以用多进程程序来代替多线程程序,但是如果你只是个屌丝的话,进程创建分配资源以及进程间的切换都会对操作系统的造成很大的辅导,资源消耗很难承受的起,相反线程,不但可以完成相同的工作,而且 系统开销还很少,那么何乐而不为呢。