进程和线程的区别-京东面试题:说一下什么是进程?什么是线程?它们有什么区别?
今天咱们聊聊技术面试中经常会被问到的一个问题:“什么是进程?什么是线程?它们之间有什么区别?”这些概念虽然听起来有点晦涩,但实际上挺有趣。为了让大家能听懂,我用一些生活化的例子加上代码带你一起搞清楚这些东西。
什么是进程?
进程是操作系统中非常核心的概念,它指的是一个正在运行的程序。可以想象你打开了一款游戏,比如《英雄联盟》,这个游戏就是一个进程。
操作系统会为这个进程分配一块独立的内存空间,并管理与之相关的资源,比如CPU时间片、内存、文件句柄等。
进程由三部分组成:程序、数据集合和进程控制块。程序是用来描述进程要完成什么任务的,数据集合则是程序运行时需要的数据,而进程控制块就像身份证一样,标识这个进程的身份和状态。
用Python来模拟一下进程的创建:
importos
defchild_process():
print(f"子进程{os.getpid()}正在运行..")
if__name__=="__main__":
print(f"父进程{os.getpid()}启动..")
pid=os.fork()#创建一个子进程
ifpid==0:
child_process()
else:
print(f"创建了子进程{pid}")
这段代码中,我们通过os.fork()创建了一个子进程,子进程会从父进程中复制一份数据,但拥有独立的执行环境。
什么是线程?
线程是比进程更轻量级的执行单元。一个进程至少会有一个线程,这个线程也被称为主线程。如果你需要让程序能“同时”干几件事,比如边下载文件边计算文件哈希值,就需要用多线程。
线程共享进程的内存和资源,所以它们之间的通信和数据共享比进程更高效。用一个生活化的例子来说,假设你在经营一家餐馆,你是老板(进程),每个员工(线程)负责一项任务,比如点单、炒菜、收银。员工们共用同一个厨房和餐具(内存资源),所以协作起来很方便。
用Python的threading模块,我们可以创建线程:
importthreading
importtime
deftask(name):
print(f"{name}线程开始执行")
time.sleep(2)
print(f"{name}线程结束执行")
if__name__=="__main__":
print("主线程开始")
thread1=threading.Thread(target=task,args=("线程1",))
thread2=threading.Thread(target=task,args=("线程2",))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print("主线程结束")
这段代码中,我们创建了两个线程,并让它们同时执行任务。注意,这里的“同时”并不是真正意义上的,因为CPU会在不同的线程间快速切换,看起来像是并行的。
进程和线程的区别
本质区别:进程是操作系统分配资源的基本单位,而线程是任务调度和执行的基本单位。简单说,进程更像是火车,线程则是车厢。
资源占用:进程有独立的代码和数据空间,每个进程的切换需要保存和加载上下文,开销较大。而线程共享进程的资源,切换开销较小。
数据共享:不同进程之间的数据共享比较困难,需要通过IPC(进程间通信)机制,比如管道、信号量、共享内存。而线程共享进程的内存,数据共享非常方便。
独立性和影响范围:一个进程的崩溃不会影响其他进程,但如果一个线程挂掉,可能会导致整个进程挂掉。
多进程和多线程的选择
多进程适用于CPU密集型任务,比如大规模的数学计算,因为它能充分利用多核CPU。多线程更适合IO密集型任务,比如文件读写、网络请求。
来看看一个简单的对比例子,分别用多进程和多线程实现:
frommultiprocessingimportProcess
importtime
defcpu_task():
print(f"进程{os.getpid()}开始执行任务")
time.sleep(2)
print(f"进程{os.getpid()}结束任务")
if__name__=="__main__":
print("主进程启动")
processes=[Process(target=cpu_task)for_inrange(3)]
forprocessinprocesses:
process.start()
forprocessinprocesses:
process.join()
print("主进程结束")
多线程示例
importthreading
importtime
defio_task():
print(f"线程{threading.current_thread().name}开始任务")
time.sleep(2)
print(f"线程{threading.current_thread().name}结束任务")
if__name__=="__main__":
print("主线程启动")
threads=[threading.Thread(target=io_task)for_inrange(3)]
forthreadinthreads:
thread.start()
forthreadinthreads:
thread.join()
print("主线程结束")
当被问到“什么是进程?什么是线程?它们的区别?”时,可以按照以下逻辑回答:
进程定义:进程是操作系统中正在运行的程序,是资源分配的基本单位,比如内存和文件句柄。
线程定义:线程是进程中的一个执行单元,是CPU调度的基本单位,多个线程共享进程的资源。
区别:
进程是独立的,线程是共享的。
进程切换开销大,线程切换开销小。
进程之间数据共享复杂,线程之间数据共享简单。
对编程、职场感兴趣的同学,大家可以联系我微信:golang404,拉你进入“程序员交流群”。
虎哥作为一名老码农,整理了全网最全。