资源分配与独立性
进程:
进程是系统进行资源分配和调度的独立单位。每个进程都有自己独立的内存空间,包括代码段、数据段、堆栈段等。这意味着一个进程无法直接访问另一个进程的内存,不同进程之间的数据是相互隔离的。例如,当你同时打开一个文本编辑器和一个浏览器,它们是两个不同的进程,分别有自己独立的内存区域来存储程序代码、打开的文件内容(在文本编辑器中)或网页数据(在浏览器中)。
这种独立性使得进程在崩溃时不会影响其他进程。如果一个进程出现错误导致崩溃,比如浏览器因为某个插件故障而崩溃,通常不会影响正在运行的文本编辑器进程。
线程:
线程是进程中的实际运作单位,它共享所属进程的资源,包括内存空间。所有线程都可以访问进程的全局变量、堆内存等。例如,在一个多线程的 Web 服务器进程中,不同的线程可能共享服务器的配置信息、缓存数据等。
由于线程共享进程的资源,所以当一个线程出现问题(如访问非法内存地址)时,可能会导致整个进程崩溃。
创建和销毁成本
进程:
创建一个进程的成本相对较高。操作系统需要为新进程分配独立的内存空间,初始化各种系统资源,如文件描述符、进程控制块等。同样,销毁一个进程也需要释放这些资源,这涉及到一系列复杂的系统操作。
例如,在 Linux 系统中,当创建一个新进程时,内核需要为其复制父进程的内存空间(通过写时复制技术来优化),设置新的进程标识符,分配新的内存页等。这些操作使得进程的创建和销毁相对较慢。
线程:
线程的创建和销毁成本相对较低。因为线程共享进程的大部分资源,创建一个线程主要是在进程的已有资源基础上分配一些线程相关的资源,如线程栈空间、线程控制块等。线程销毁时,主要是释放这些特定于线程的资源。
例如,在 Python 的threading模块中创建一个线程,不需要像创建进程那样进行复杂的内存分配和初始化操作,所以速度更快。
切换成本
进程:
进程切换的成本较高。当操作系统从一个进程切换到另一个进程时,需要保存当前进程的状态(包括程序计数器、寄存器内容、内存管理信息等),然后加载下一个进程的状态。这个过程涉及到操作系统内核的模式切换和大量的上下文信息保存与恢复,会消耗较多的时间和系统资源。
例如,在一个多任务操作系统中,如果有多个进程在运行,当从一个 CPU 密集型的进程(如进行复杂数学计算的进程)切换到一个 I/O 密集型的进程(如等待网络数据的进程)时,操作系统需要进行完整的进程上下文切换。
线程:
线程切换的成本相对较低。由于线程共享进程的内存空间和其他资源,线程切换时主要是保存和恢复线程的执行上下文(如程序计数器、寄存器内容等),不需要像进程切换那样涉及到复杂的内存管理等操作。
例如,在一个多线程的应用程序中,线程之间的切换相对较快,因为它们共享大部分的进程资源,内核不需要重新加载内存映射等信息。
并发性能与适用场景
进程:
进程适合用于需要高度隔离和稳定性的场景,如运行不同的应用程序或者在多核系统中充分利用多核资源来执行相互独立的任务。例如,在一个服务器上同时运行 Web 服务器、数据库服务器和邮件服务器等不同的服务,每个服务作为一个独立的进程,可以更好地隔离资源,提高系统的稳定性和安全性。
对于 CPU 密集型任务,多个进程可以充分利用多核 CPU 的多个核心,实现真正的并行计算,从而提高性能。
线程:
线程适用于 I/O 密集型任务,因为在等待 I/O 操作(如网络请求、磁盘读取等)完成时,线程可以让出 CPU 资源,让其他线程执行。例如,在一个网络爬虫程序中,线程可以在等待网页内容下载的过程中,让其他线程进行其他网页的下载请求,从而提高程序的整体效率。
由于线程共享资源,在访问共享资源时需要注意线程同步问题,否则可能会出现数据不一致等错误。所以在使用线程时,需要谨慎处理共享资源的访问。
标签:Python,编程,一个,线程,内存,进程,资源,切换 From: https://blog.csdn.net/weixin_47362565/article/details/144613835