1. 进程与线程区别
从概念上:
进程:一个程序对一个数据集的动态执行过程,是分配资源的基本单位。
线程:一个进程内的基本调度单位。
线程的划分尺度小于进程,一个进程包含一个或者更多的线程。
从执行过程中来看:
进程:拥有独立的内存单元,而多个线程共享内存,从而提高了应用程序的运行效率。
线程:每一个独立的线程,都有一个程序运行的入口、顺序执行序列、和程序的出口。但是线程不能够独立的执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
从逻辑角度来看:(重要区别)
多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但是,操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理及资源分配。
2. 我们写的程序,不论是C、C++、java还是其他的,其实都是一种文本,真正运行、跑动的是进程。
程序可以分为两部分:源代码和可执行的二进制代码(经过汇编或编译)。操作系统加载这个可执行的二进制代码后,还要分配相应的内核数据结构——进程控制块(PCB:process control block),并进行一系列的初始化等过程(如:创建PID、分配时间片等)后才创建了真正可以“跑动”的进程。所以程序相当于是一个项目的计划书(或行动方案),而进程才是对该方案的实施过程。
进程对CPU来说其实就是一串可执行的指令序列,这个执行序列也叫执行线程,它是进程的控制流程。传统的用户进程只有一个执行流程,所以传统的进程都是单线程的。有了线程就是执行流程的概念后,进程模型得到了扩展,因为一个进程中完全可以设置多个执行流程,即多个执行线程。所以一个进程中可以创建多个线程,当然不创建的话,进程本身也可以看成是线程。
创建多个进程的话,每个进程都是独立的(都有自己独立的PCB数据结构,该数据结构比较大,将近1K的信息量,包括唯一的PID、上下文环境、持有的内存地址等等),内核要管理进程间的切换、内存管理等,开销相对比较大。
如果一个进程里创建多个线程的话,开销比进程要小,各线程共享进程的状态和资源,内核为线程创建的数据结构相对比进程的PCB就要小的多,当然额外的开销是CPU需要跟踪线程,同时线程间存在争用资源的问题。如果程序要完成一组相关任务,则用线程比较好。
下面再细讲下进程:
我们知道进程可以创建子进程,由于在分时系统中进程都有时间片(进程每次调度到时可以运行的时间),用户其实可以通过创建更多的子进程来获取较多的CPU时间和系统资源。
创建进程的函数有:fork()、clone()和vfork()。它们的区别是:用fork创建的子进程是父进程的一个copy(地址空间副本),但它们除了代码段外,并不共享任何内容;clone根据提供的clone_flags参数来决定父子进程应该共享的内容,当不提供该参数任何标志值时,父子进程也不共享任何内容,此时跟fork一样的效果。如果提供了所有的标志,则父子进程共享任何内容,这也就是传统的线程;vfork不进行进程复制,它将自己的地址空间租给子进程,并将自己阻塞,等子进程运行结束时将地址空间还给父进程。vfork一般用于fork一个子进程,子进程却调用了exec()的情况(下面说明),vfork调用非常快,当然它也是一个非常危险的系统调用,因为租用期子进程可以修改父进程的地址空间信息。
为什么会有vfork呢?就是因为我fork出来的子进程往往会调用exec函数来执行新的程序(创建子进程一般就是为了执行其他程序,很少是为了执行跟父进程一样的代码),在fork时我们知道会创建跟父进程一模一样的地址空间副本,但当调用exec()执行一个新程序时,又会丢弃这个地址空间(创建和利用的其实是新程序相应的地址空间),这显然是对资源的浪费了。
964

被折叠的 条评论
为什么被折叠?



