进程和线程的选择
- 格式:doc
- 大小:35.50 KB
- 文档页数:2
进程线程练习题一、选择题1. 进程是指()。
a) 线程的集合b) 代码的集合c) 资源的集合d) 程序的集合2. 线程是指()。
a) 进程的集合b) 代码的集合c) 资源的集合d) 程序的集合3. 在操作系统中,多个进程可以通过()来实现并发执行。
a) 共享内存b) 进程间通信c) 线程d) 同步操作4. 下列关于进程和线程的说法中,错误的是()。
a) 进程是资源分配的最小单位b) 线程是程序执行的最小单位c) 进程之间是相互独立的d) 线程之间共享内存空间5. 在Java中,可以创建线程的两种方式是()。
a) 继承Thread类、实现Runnable接口b) 实现Thread类、继承Runnable接口c) 实现Thread接口、继承Runnable类d) 继承Thread类、实现Callable接口二、填空题1. 进程间通信的方式有()。
2. 线程可以共享的资源有()。
3. 线程调度的方式包括()和()。
三、简答题1. 请简述进程和线程的概念及区别。
2. 进程间通信的方式有哪些,各自的优缺点是什么?3. 线程调度的方式有哪些,各自的优缺点是什么?4. 请举例说明多线程的优势以及适用场景。
四、编程题请使用Java语言编写一个多线程程序,实现以下功能:1. 创建两个线程T1和T2,分别打印出1~5和6~10的数字。
2. 要求线程T1和T2交替执行,即先打印数字1,然后打印数字6,接着打印数字2,再打印数字7,以此类推。
3. 在程序中使用合适的同步机制来实现线程的交替执行。
答案:一、选择题1. a) 线程的集合2. b) 代码的集合3. b) 进程间通信4. d) 线程之间共享内存空间5. a) 继承Thread类、实现Runnable接口二、填空题1. 管道通信、消息队列、共享内存、信号量、套接字通信等2. 内存空间3. 抢占式调度、协同式调度三、简答题1. 进程是操作系统进行资源分配和调度的基本单位。
进程切换与线程切换的区别⼀、什么是虚拟内存虚拟内存是操作系统为每个进程提供的⼀种抽象,每个进程都有属于⾃⼰的,私有的、地址连续的虚拟内存,当然我们知道最终进程的数据及代码必然要放到物理内存上,那么必须有某种机制能记住虚拟地址空间中的某个数据被放到了那个物理内存地址上,这就是所谓的地址空间映射,也就是虚拟内存地址与物理地址的映射关系,操作系统通过页表记住这种映射关系,页表中记录了虚拟内存地址到物理内存地址的映射关系。
有了页表就可以将虚拟地址转换为物理内存地址了,这种机制就是虚拟内存。
⼆、进程切换和线程切换的区别进程切换与线程切换的⼀个最主要区别就在于进程切换涉及到虚拟地址空间的切换⽽线程切换则不会。
因为每个进程都有⾃⼰的虚拟地址空间,⽽线程是共享所在进程的虚拟地址空间的,因此同⼀个进程中的线程进⾏线程切换时不涉及虚拟地址空间的转换。
举⼀个不太恰当的例⼦,线程切换就好⽐你从主卧⾛到次卧,反正主卧和次卧都在同⼀个房⼦中(虚拟地址空间),因此你⽆需换鞋⼦、换⾐服等等。
但是进程切换就不⼀样了,进程切换就好⽐从你家到别⼈家,这是两个不同的房⼦(不同的虚拟地址空间),出发时要换好⾐服、鞋⼦等等,到别⼈家后还要再换鞋⼦等等。
因此我们可以形象的认为线程是处在同⼀个屋檐下的,这⾥的屋檐就是虚拟地址空间,因此线程间切换⽆需虚拟地址空间的切换;⽽进程则不同,两个不同进程位于不同的屋檐下,即进程位于不同的虚拟地址空间,因此进程切换涉及到虚拟地址空间的切换,这也是为什么进程切换要⽐线程切换慢的原因。
三、为什么虚拟地址切换很慢现在我们已经知道了进程都有⾃⼰的虚拟地址空间,把不腻地址转化为物理地址需要查找页表,页表查找是⼀个很慢的过程,因此通常使⽤Cache来缓存常⽤的地址映射,这样可以加速页表查找,这个Cache就是TLB,Translation Lookaside Buffer,我们不需要关⼼这个名字,只需要知道TLB本质上就是⼀个cache,是⽤来加速页表查找的。
多线程与多进程的使⽤场景io 操作不占⽤CPU(从硬盘、从⽹络、从内存读数据都算io)计算占⽤CPU(如1+1计算)python中的线程是假线程,不同线程之间的切换是需要耗费资源的,因为需要存储线程的上下⽂,不断的切换就会耗费资源。
python多线程适合io操作密集型的任务(如socket server ⽹络并发这⼀类的);python多线程不适合cpu密集操作型的任务,主要使⽤cpu来计算,如⼤量的数学计算。
那么如果有cpu密集型的任务怎么办,可以通过多进程来操作(不是多线程)。
假如CPU有8核,每核CPU都可以⽤1个进程,每个进程可以⽤1个线程来进⾏计算。
进程之间不需要使⽤gil锁,因为进程是独⽴的,不会共享数据。
进程可以起很多个,但是8核CPU同时只能对8个任务进⾏操作。
多进程测试多进程import multiprocessingimport timedef run(name):time.sleep(2)print ('heelo',name)if __name__ == '__main__':for i in range(10): #起了10个进程p = multiprocessing.Process(target=run,args=('bob%s' %i,))p.start()执⾏结果:heelo bob1heelo bob0heelo bob2heelo bob3heelo bob5heelo bob4heelo bob6heelo bob7heelo bob8heelo bob9##2秒左右就执⾏完成了,有⼏核CPU,同时就可以处理⼏个进程;当然要考虑你的电脑还开启了N多个其他应⽤程序,不过CPU计算⽐较快。
import multiprocessingimport time,threadingdef thread_run():print (threading.get_ident()) #get_ident获取当前线程iddef run(name):time.sleep(2)print ('heelo',name)t = threading.Thread(target=thread_run,) #在每个进程中⼜起了1个线程t.start()if __name__ == '__main__':for i in range(10): #起了10个进程p = multiprocessing.Process(target=run,args=('bob%s' %i,))p.start()执⾏结果:heelo bob016684heelo bob115052heelo bob215260heelo bob36192heelo bob46748heelo bob713980heelo bob56628heelo bob63904heelo bob92328heelo bob817072import osdef info(title):print(title)print('module name:', __name__)print('parent process:', os.getppid()) #获取⽗进程的idprint('process id:', os.getpid()) #获取⾃⾝的idprint("\n\n")def f(name):info('\033[31;1mfunction f\033[0m')print('hello', name)if __name__ == '__main__':info('\033[32;1mmain process line\033[0m') ##直接调⽤函数# p = Process(target=f, args=('bob',))# p.start()# p.join()执⾏结果:main process linemodule name: __main__parent process: 1136 #⽗进程ID,这个⽗进程就是pycharmprocess id: 16724 #这个⼦进程就是python的代码程序##每个进程都会有⼀个⽗进程。
CPU 如何选择线程在Linux 内核中,进程和线程都是用tark_struct 结构体表示的,区别在于线程的tark_struct 结构体里部分资源是共享了进程已创建的资源,比如内存地址空间、代码段、文件描述符等,所以Linux 中的线程也被称为轻量级进程,因为线程的tark_struct 相比进程的tark_struct 承载的资源比较少,因此以「轻」得名。
一般来说,没有创建线程的进程,是只有单个执行流,它被称为是主线程。
如果想让进程处理更多的事情,可以创建多个线程分别去处理,但不管怎么样,它们对应到内核里都是tark_struct。
所以,Linux 内核里的调度器,调度的对象就是tark_struct,接下来我们就把这个数据结构统称为任务。
在Linux 系统中,根据任务的优先级以及响应要求,主要分为两种,其中优先级的数值越小,优先级越高:•实时任务,对系统的响应时间要求很高,也就是要尽可能快的执行实时任务,优先级在0~99 范围内的就算实时任务;•普通任务,响应时间没有很高的要求,优先级在100~139 范围内都是普通任务级别;1、调度类由于任务有优先级之分,Linux 系统为了保障高优先级的任务能够尽可能早的被执行,于是分为了这几种调度类,如下图:Deadline 和Realtime 这两个调度类,都是应用于实时任务的,这两个调度类的调度策略合起来共有这三种,它们的作用如下:•SCHED_DEADLINE:是按照deadline 进行调度的,距离当前时间点最近的deadline 的任务会被优先调度;•SCHED_FIFO:对于相同优先级的任务,按先来先服务的原则,但是优先级更高的任务,可以抢占低优先级的任务,也就是优先级高的可以「插队」;•SCHED_RR:对于相同优先级的任务,轮流着运行,每个任务都有一定的时间片,当用完时间片的任务会被放到队列尾部,以保证相同优先级任务的公平性,但是高优先级的任务依然可以抢占低优先级的任务;而Fair 调度类是应用于普通任务,都是由CFS 调度器管理的,分为两种调度策略:•SCHED_NOR M AL:普通任务使用的调度策略;•SCHED_B A T CH:后台任务的调度策略,不和终端进行交互,因此在不影响其他需要交互的任务,可以适当降低它的优先级。
rtos进程线程的理解
RTOS(实时操作系统)中的进程和线程是两个重要的概念,它们在RTOS 中的理解和常见操作系统中的进程和线程有所不同。
以下是关于RTOS中进程和线程的理解:
1.进程在RTOS中通常指的是一个独立的执行单元,具有独立的地址空间和系
统资源。
每个进程都有自己的内存空间、文件句柄、网络连接等资源,彼此之间相互隔离,互不影响。
RTOS中的进程类似于常见操作系统中的进程,但RTOS中的进程通常更轻量级,创建和销毁的开销更小。
2.线程在RTOS中通常指的是一个执行流,它是RTOS进行调度和执行的基本
单位。
线程在进程内部共享进程的资源,包括内存空间、文件句柄等。
一个进程中可以有一个或多个线程,这些线程共享进程的资源,但有自己的执行上下文。
线程的创建和销毁的开销相对较小,适合于快速切换和轻量级任务。
3.线程和进程的区别在于,线程之间共享进程的资源,而进程之间相互隔离。
线程的切换速度快,适合于轻量级任务的快速切换,而进程的创建和销毁开销较大,适合于独立执行单元的任务。
4.在RTOS中,任务可以被看作是一个具有独立功能的代码段,它可以被分配
给一个进程或线程来执行。
任务可以有优先级和调度参数,RTOS根据这些参数进行任务的调度和执行。
总的来说,RTOS中的进程和线程是两个重要的概念,它们各自有其特点和适用场景。
选择使用进程还是线程取决于具体的应用需求和系统设计。
进程和线程⾯试题1、线程和进程线程:线程是进程的⼀个实体,是CPU调度和分派的基本单元。
进程:进程是具有⼀定独⽴功能的程序,它是系统进程资源分配和调度的⼀个独⽴单元。
区别:(1)⼀个线程只属于⼀个进程,⼀个进程包含⼀个或者多个线程。
(2)进程拥有独⽴的内存单元,⽽多个线程共享内存。
(3)进程的创建调⽤fork或者vfork,⽽线程的创建调⽤pthead_create,进程结束后它拥有的所有线程都将销毁,⽽线程的结束不会影响同个进程中的其他线程的结束。
(4)线程是轻量级的进程,它的创建和销毁所需要的时间⽐进程⼩很多,所有操作系统中的执⾏功能都是创建线程去完成的。
(5)线程中执⾏时⼀般都要进⾏同步和互斥,因为他们共享同⼀进程的资源。
2、死锁?死锁产⽣的原因?死锁的必要条件?怎么处理死锁?死锁:死锁是指两个或者两个以上的进程在执⾏过程中,由于竞争资源或者由于彼此通信⽽造成的⼀种阻塞的现象。
死锁原因:系统资源不⾜、相互竞争资源。
请求资源顺序不当死锁的必要条件:1.互斥条件:⼀个资源每次只能被⼀个进程使⽤。
2.请求和保持条件:⼀个进程因请求资源⽽阻塞时,对已获得的资源保持不放。
3.不可剥夺条件:进程已获得的资源,在未使⽤完之前,不能强⾏剥夺,只能在进程使⽤完时由⾃⼰释放。
4.循环等待条件:若⼲进程之间形成⼀种头尾相接的循环等待资源关系。
避免死锁的⽅法:因为互斥是不可改变的,所以只能破坏其他三个条件中的⼀个来解除死锁,⽅法:剥夺资源、杀死其中⼀个线程。
避免死锁最简单的⽅法就是阻⽌循环等待条件,将系统中所有的资源设置标志位、排序,规定所有的进程申请资源必须以⼀定的顺序做操作来避免死锁。
3、如何在Java中实现线程?(1)继承Thread类(2)实现Runnable接⼝(3)实现Callable接⼝通过FutureTask包装器来创建Thread线程(4)使⽤ExecutorService、Callable、Future实现有返回结果的多线程4、⽤Runnable还是Thread?Java不⽀持类的多重继承,但允许你调⽤多个接⼝(当然是调⽤Runnable接⼝更好)5、Thread类中start()和run()⽅法有什么区别?(1)start()⽅法被⽤来启动新创建的线程,⽽start()内部调⽤了run()⽅法。
进程与线程的定义、关系及区别进程与线程的定义、关系及区别⼀、进程的定义进程:指在系统中能独⽴运⾏并作为资源分配的基本单位,它是由⼀组机器指令、数据和堆栈等组成的,是⼀个能独⽴运⾏的活动实体。
进程⼀般有三个状态:就绪状态、执⾏状态和等待状态【或称阻塞状态】;进程只能由⽗进程建⽴,系统中所有的进程形成⼀种进程树的层次体系;挂起命令可由进程⾃⼰和其他进程发出,但是解除挂起命令只能由其他进程发出。
进程控制块(PCB):PCB不但可以记录进程的属性信息,以便对进程进⾏控制和管理,⽽且PCB标志着进程的存在,操作系统根据系统中是否有该进程的进程控制块PCB⽽知道该进程存在与否。
系统建⽴进程的同时就建⽴该进程的PCB,在撤销⼀个进程时,也就撤销其PCB,故进程的PCB对进程来说是它存在的具体的物理标志和体现。
⼀般PCB包括以下三类信息:进程标识信息;处理器状态信息;进程控制信息。
由程序段、相关的数据段和PCB三部分构成了进程实体(⼜称进程印像),⼀般,我们把进程实体就简称为进程。
进程的特征:1.动态性:进程的实质是程序的⼀次执⾏过程,进程是动态产⽣,动态消亡的。
2.并发性:任何进程都可以同其他进程⼀起并发执⾏。
3.独⽴性:进程是⼀个能独⽴运⾏的基本单位,同时也是系统分配资源和调度的独⽴单位。
4.异步性:由于进程间的相互制约,使进程具有执⾏的间断性,即进程按各⾃独⽴的、不可预知的速度向前推进。
⼆、线程的定义线程:线程是进程中的⼀个实体,作为系统调度和分派的基本单位。
线程的性质:1.线程是进程内的⼀个相对独⽴的可执⾏的单元。
若把进程称为任务的话,那么线程则是应⽤中的⼀个⼦任务的执⾏。
2.由于线程是被调度的基本单元,⽽进程不是调度单元。
所以,每个进程在创建时,⾄少需要同时为该进程创建⼀个线程。
即进程中⾄少要有⼀个或⼀个以上的线程,否则该进程⽆法被调度执⾏。
3.进程是被分给并拥有资源的基本单元。
同⼀进程内的多个线程共享该进程的资源,但线程并不拥有资源,只是使⽤他们。
进程和线程的区别进程:指在系统中正在运⾏的⼀个应⽤程序;程序⼀旦运⾏就是进程;或者更专业化来说:进程是指程序执⾏时的⼀个实例,即它是程序已经执⾏到课中程度的数据结构的汇集。
从内核的观点看,进程的⽬的就是担当分配系统资源(CPU时间、内存等)的基本单位。
线程:系统分配处理器时间资源的基本单元,或者说进程之内独⽴执⾏的⼀个单元执⾏流。
进程——资源分配的最⼩单位,线程——程序执⾏的最⼩单位。
线程进程的区别体现在4个⽅⾯:1、因为进程拥有独⽴的堆栈空间和数据段,所以每当启动⼀个新的进程必须分配给它独⽴的地址空间,建⽴众多的数据表来维护它的代码段、堆栈段和数据段,这对于多进程来说⼗分“奢侈”,系统开销⽐较⼤,⽽线程不⼀样,线程拥有独⽴的堆栈空间,但是共享数据段,它们彼此之间使⽤相同的地址空间,共享⼤部分数据,⽐进程更节俭,开销⽐较⼩,切换速度也⽐进程快,效率⾼,但是正由于进程之间独⽴的特点,使得进程安全性⽐较⾼,也因为进程有独⽴的地址空间,⼀个进程崩溃后,在保护模式下不会对其它进程产⽣影响,⽽线程只是⼀个进程中的不同执⾏路径。
⼀个线程死掉就等于整个进程死掉。
2、体现在通信机制上⾯,正因为进程之间互不⼲扰,相互独⽴,进程的通信机制相对很复杂,譬如管道,信号,消息队列,共享内存,套接字等通信机制,⽽线程由于共享数据段所以通信机制很⽅便。
3、体现在CPU系统上⾯,线程使得CPU系统更加有效,因为操作系统会保证当线程数不⼤于CPU数⽬时,不同的线程运⾏于不同的CPU 上。
4、体现在程序结构上,举⼀个简明易懂的列⼦:当我们使⽤进程的时候,我们不⾃主的使⽤if else嵌套来判断pid,使得程序结构繁琐,但是当我们使⽤线程的时候,基本上可以甩掉它,当然程序内部执⾏功能单元需要使⽤的时候还是要使⽤,所以线程对程序结构的改善有很⼤帮助。
什么情况下使⽤进程个线程:1、需要频繁创建销毁的优先使⽤线程;因为对进程来说创建和销毁⼀个进程代价是很⼤的2、线程的切换速度快,所以在需要⼤量计算,切换频繁时⽤线程,还有耗时的操作使⽤线程可提⾼应⽤程序的响应3、因为对CPU系统的效率使⽤上线程更占优,所以可能要发展到多机分布的⽤进程,多核分布⽤线程4、并⾏操作时使⽤线程,如C/S架构的服务器端并发线程响应⽤户的请求5、需要更稳定安全时,适合选择进程;需要速度时,选择线程更好因为我的项⽬中需要对数据段的数据共享,可以被多个程序所修改,所以使⽤线程来完成此操作,⽆需加⼊复杂的通信机制,使⽤进程需要添加复杂的通信机制实现数据段的共享,增加了我的代码的繁琐,⽽且使⽤线程开销⼩,项⽬运⾏的速度快,效率⾼。
为什么要引⼊线程?线程为什么能弥补进程的缺点⾸先我们需要明⽩,线程与进程⼀样,线程和进程会被os统⼀调度,所以所有的线程和进程都是⼀起并发运⾏的,如果线程不是并发的,是不可能实现程序的多线任务的。
有了线程以后,凡是程序涉及到多线任务时,都使⽤多线程来实现,使⽤多线程来实现时,线程间的切换和数据通信的开销⾮常低,正因为开销⾮常低,因此线程还有另⼀个名称,叫”轻量级的进程“。
总结的讲,说⽩了线程就是为了多线任务⽽⽣的,多线程的多线⼆字,不就是多线任务的多线⼆字吗。
疑问:使⽤线程来实现时,线程也需要切换和通信,这不跟进程⼀样吗?为什么线程就能降低切换和通信的开销呢?为什么线程切换的开销很低使⽤多进程来实现程序的多线任务,多线并发运⾏时,涉及到的是进程间的切换,我们前⾯就说过,进程间切换时开销⾮常⼤。
但是使⽤多线程来实现多线任务,由于线程本质上它只是程序(进程)的⼀个函数,只不过线程函数与普通函数的区别是,普通函数时单线的运⾏关系,⽽线程函数被注册为线程后,是多线并发运⾏,如图所⽰。
对于普通函数来说,只有当相互调动时才会涉及函数间的切换,但是对于线程函数来说,只要运⾏的时间⽚到了就会切换,但是不管是那种函数间的切换,进程⾃⼰函数的切换只是进程内部的事情,不涉及进程间切换,函数切换当然也需要开销,但是这些开销相⽐进程间就省去了进程间切换的巨⼤开销。
当然如果是不同进程的线程之间需要切换的话,还是会涉及到进程间的切换的,但是不管怎么说,线程的出现,⾄少为程序内部多线任务之间的切换,省去了⼤笔的进程切换所导致“资源开销”。
为什么线程间数据通信的开销很低线程的本质就是函数,请问⼤家函数之间如果想要数据共享(通信)的话,应该怎么办?函数间通信有两种⽅式:(1)具有相互调⽤关系函数来说使⽤函数传参来通信。
(2)对于没有调⽤关系的函数来说使⽤全局变量来通信。
A函数⼀⼀>全变变量⼀⼀>B函数所以说全局变量的作⽤是什么?就是⽤来实现⽆调⽤关系的函数间通信的。
进程和线程是什么关系与区别
进程
进程是程序的⼀次执⾏过程,是⼀个动态概念,是程序在执⾏过程中分配和管理资源的基本单位,每⼀个进程都有⼀个⾃⼰的地址空间,⾄少有5 种基本状态,它们是:初始态,执⾏态,等待状态,就绪状态,终⽌状态。
线程
线程是CPU调度和分派的基本单位,它可与同属⼀个进程的其他的线程共享进程所拥有的全部资源。
【进程是资源分配的最⼩单位,线程是CPU调度的最⼩单位】
进程和线程的关系
线程是进程的⼀部分
⼀个线程只能属于⼀个进程,⽽⼀个进程可以有多个线程,但⾄少有⼀个线程
进程和线程的区别
理解它们的差别,我从资源使⽤的⾓度出发。
(所谓的资源就是计算机⾥的中央处理器,内存,⽂件,⽹络等等)
根本区别:进程是操作系统资源分配的基本单位,⽽线程是任务调度和执⾏的基本单位
开销⽅⾯:每个进程都有独⽴的代码和数据空间(程序上下⽂),进程之间切换开销⼤;线程可以看做轻量级的进程,同⼀类线程共享代码和数据空间,每个线程都有⾃⼰独⽴的运⾏栈和程序计数器(PC),线程之间切换的开销⼩
所处环境:在操作系统中能同时运⾏多个进程(程序);⽽在同⼀个进程(程序)中有多个线程同时执⾏(通过CPU调度,在每个时间⽚中只有⼀个线程执⾏)
内存分配:系统为每个进程分配不同的内存空间;⽽对线程⽽⾔,除了CPU外,系统不会为线程分配内存(线程所使⽤的资源来⾃其所属进程的资源),线程组之间只能共享资源
包含关系:线程是进程的⼀部分,所以线程也被称为轻权进程或者轻量级进程。
Linux学习知识点--进程和线程有什么区别进程和线程的区别学习Linu某来说并不是一件简单的事情,之前作为一个非常的网管大神,遇到Linu某的时候还是表示胡一脸的蒙蔽,真正系统学习了之后才知道这个非常乏味却又充满未知的领域是多么的吸引我的注意。
线程是进程的一个执行流,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。
一个进程由几个线程组成(拥有很多相对独立的执行流的用户程序共享应用程序的大部分数据结构),线程与同属一个进程的其他的线程共享进程所拥有的全部资源。
"进程——资源分配的最小单位,线程——程序执行的最小单位"进程从内核的观点看,进程的目的就是担当分配系统资源(CPU时间、内存等)的基本单位。
是程序执行时的一个实例,即它是程序已经执行到课中程度的数据结构的汇集。
进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。
线程有自己的堆栈和局部变量,但线程没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。
但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
总的来说就是:进程有独立的地址空间,线程没有单独的地址空间(同一进程内的线程共享进程的地址空间)。
(下面的内容摘自Linu某下的多线程编程)使用多线程的理由之一是和进程相比,它是一种非常"节俭"的多任务操作方式。
我们知道,在Linu某系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种"昂贵"的多任务工作方式。
而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。
linux线程切换和进程切换的⽅法进程切换分两步:1.切换页⽬录以使⽤新的地址空间2.切换内核栈和硬件上下⽂对于linux来说,线程和进程的最⼤区别就在于地址空间,对于线程切换,第1步是不需要做的,第2是进程和线程切换都要做的。
切换的性能消耗:1、线程上下⽂切换和进程上下问切换⼀个最主要的区别是线程的切换虚拟内存空间依然是相同的,但是进程切换是不同的。
这两种上下⽂切换的处理都是通过操作系统内核来完成的。
内核的这种切换过程伴随的最显著的性能损耗是将寄存器中的内容切换出。
2、另外⼀个隐藏的损耗是上下⽂的切换会扰乱处理器的缓存机制。
简单的说,⼀旦去切换上下⽂,处理器中所有已经缓存的内存地址⼀瞬间都作废了。
还有⼀个显著的区别是当你改变虚拟内存空间的时候,处理的页表缓冲(processor's Translation Lookaside Buffer (TLB))或者相当的神马东西会被全部刷新,这将导致内存的访问在⼀段时间内相当的低效。
但是在线程的切换中,不会出现这个问题。
系统调⽤:处于进程上下⽂系统调⽤是在进程上下⽂中,并没有tasklet之类的延迟运⾏,系统调⽤本⾝可以休眠,这些可以参见内核代码虽然系统调⽤实与其他中断实现有点类似,通过IDT表查找⼊⼝处理函数,但是系统调⽤与其他中断最⼤的不同是,系统调⽤是代表当前进程执⾏的,所以current宏/task_struct是有意义的,这个休眠可以被唤醒系统调⽤,异常,中断(其中中断是异步时钟,异常时同步时钟),也可以把系统调⽤成为异常中断上下⽂:在中断中执⾏时依赖的环境,就是中断上下⽂(不包括系统调⽤,是硬件中断)进程上下⽂:当⼀个进程在执⾏时,CPU的所有寄存器中的值、进程的状态以及堆栈中的内容被称为该进程的上下⽂1、⾸先,这两个上下⽂都处于内核空间。
2、其次,两者的区别在于,进程上下⽂与当前执⾏进程密切相关,⽽中断上下⽂在逻辑上与进程没有关系。
进程和线程的区别和联系
联系:1、线程是进程的最⼩执⾏和分配单元,不能独⽴运动,必须依赖于进程,这也就可以说众多的线程组成了进程
2、同⼀个进程中的线程是共享内存资源的,⽐如全局变量,每⼀个线程都可以改变其共同进程中的全局变量的数据
区别:1、进程是程序在系统上进⾏顺序执⾏的动态活动。
程序加载到内存,系统为其分配内存空间⽽执⾏,⽽这种执⾏的程序称之为进程(程序是指令的集合,是程序运⾏的静态描述⽂本)
2、进程是操作系统进⾏分配(⽐如内存)的最基本单位,线程是cpu能够进⾏调度和分派的最基本单位
3、进程下管理的最底层单位是线程,在等级上,进程明显⼤于线程
4、⼀个程序可以有多个进程,⼀个进程可以有多个线程(⼀个进程⾥⾄少有⼀个线程),进程是拥有其独⽴的内存单元地址空间,⽽线程共享进程中的资源,所以极⼤的提⾼了程序的运⾏效率
5、线程基本不拥有系统资源,它与其他线程共享同⼀进程所拥有的共同资源。
由于线程⽐进程⼩,且基本不拥有系统资源,因此对其调度的开销会很⼩,从⽽极⼤的提⾼了对系统资源的利⽤率
6、当服务器需要响应多个⽤户请求时,如果创建多个进程,由于进程与进程之间是相互独⽴的,会过多的占⽤内存空间,降低服务器的响应速度,但线程是共享同⼀进程中的资源的,使⽤线程会提⾼系统的并发型。
进程、线程、协程之概念理解+线程和进程各⾃有什么区别和优劣⼀、概念⾸先,根据图了解⼀下串⾏,并⾏和并发的基本概念: 1、进程 资源分配的基本单位进程(Process)是计算机中的程序关于某数据集合上的⼀次运⾏活动,是系统进⾏资源分配和调度的基本单位,是操作系统结构的基础。
在早期⾯向进程设计的计算机结构中,进程是程序的基本执⾏实体;在当代⾯向线程设计的计算机结构中,进程是线程的容器。
程序是指令、数据及其组织形式的描述,进程是程序的实体。
Linux系统函数fork()可在⽗进程中创建⼀个⼦进程,在⽗进程接到新请求时,复制出⼀个⼦进程来处理,即⽗进程监控请求,⼦进程处理,实现并发处理。
注意:必须是Linux系统,windows不能⽤fork。
组成进程是⼀个实体。
每⼀个进程都有它⾃⼰的地址空间,⼀般情况下,包括⽂本区域(text region)、数据区域(data region)和堆栈(stack region)。
⽂本区域存储处理器执⾏的代码;数据区域存储变量和进程执⾏期间使⽤的动态分配的内存;堆栈区域存储着活动过程调⽤的指令和本地变量。
特征动态性:进程的实质是程序在多道程序系统中的⼀次执⾏过程,进程是动态产⽣,动态消亡的。
并发性:任何进程都可以同其他进程⼀起并发执⾏独⽴性:进程是⼀个能独⽴运⾏的基本单位,同时也是系统分配资源和调度的独⽴单位;异步性:由于进程间的相互制约,使进程具有执⾏的间断性,即进程按各⾃独⽴的、不可预知的速度向前推进结构特征:进程由程序、数据和进程控制块三部分组成。
多个不同的进程可以包含相同的程序:⼀个程序在不同的数据集⾥就构成不同的进程,能得到不同的结果;但是执⾏过程中,程序不能发⽣改变。
进程的⼏种状态(1)run(运⾏状态):正在运⾏的进程或在等待队列中等待的进程,等待的进程只要以得到cpu就可以运⾏(2)Sleep(可中断休眠状态):相当于阻塞或在等待的状态(3)D(不可中断休眠状态):在磁盘上的进程(4)T(停⽌状态):这中状态⽆法直观的看见,因为是进程停⽌后就释放了资源,所以不会留在linux中(5)Z(僵⼫状态):⼦进程先与⽗进程结束,但⽗进程没有调⽤wait或waitpid来回收⼦进程的资源,所以⼦进程就成了僵⼫进程,如果⽗进程结束后任然没有回收⼦进程的资源,那么1号进程将回收 2、线程 CPU调度和分配的基本单位,程序执⾏的最⼩单位。
进程进程的概念进程的状态进程的控制结构进程的控制进程的上下文切换线程为什么要使用线程?线程与进程的比较线程的上下文切换线程的实现调度调度时机调度原则调度算法进程进程的概念进程就是具有独立功能的程序关于某一数据集合的一次运行活动。
就如我下面的截图,比如WeChat(微信桌面版),这其实就是针对具体功能的运行活动称为进程,但是可以看到进程内还有很多细项在运行,所以也可以称这是一个WeChat的进程树。
进程的状态大家都知道CPU运算是非常快的,但是程序呢不一定都是一泻千里一口气运行到底的,就像我拿个热水壶烧水一样,我已经执行完“接水”==》放热水壶==》插电==》摁开关,但是烧水是需要时间的,我不能在这呆呆的等着,我还可以干点别的,一直到热水壶发出声音提醒我,我去“倒开水”这才完成。
那么我烧水这一连串的动作就可以看作一个进程,那么在这个过程中,就有个“运行”==》“暂停”==》“运行”这样的一种情况。
这种“间断”的特性,也就决定了进程有的三种基本状态:•就绪–进程准备好了除CPU之外的所有资源,就等CPU执行了。
•运行–CPU正在执行当前进程。
•阻塞–进程需要达到某种条件才可以继续执行,在条件满足之前即使得到了CPU资源也无法执行下去。
从头开始到结束呢就还有两个状态•新建–从一无所有创建一个进程,进入就绪状态。
•结束–进程活动完成(正常结束、异常结束)。
另外还有就是常说的挂起状态:进程不再占用内存空间了•就绪挂起–进程在硬盘上,除了CPU之外的资源准备好了,只要加载进内存立马进入就绪状态。
•阻塞挂起–进程在硬盘上,需要满足某种条件,满足条件后被加载进内存进入就绪状态,没有满足条件被加载进内存则进入阻塞状态。
进程的控制结构上面提到进程有这么些状态,那又是怎么控制的呢?在操作系统中,是用进程控制块(process control block,PCB)数据结构来描述进程的。
系统用PCB来记录进程的外部特征,描述进程的运动变化,是感知进程存在的唯一标志。
简述进程、线程、协程的区别以及应⽤场景?
1.进程是计算器最⼩资源分配单位 .
2.线程是CPU调度的最⼩单位 .
3.进程切换需要的资源很最⼤,效率很低 .
4.线程切换需要的资源⼀般,效率⼀般(当然了在不考虑GIL的情况下) .
5.协程切换任务资源很⼩,效率⾼(协程本⾝并不存在,是程序员通过控制IO操作完成) .
6.多进程、多线程根据cpu核数不⼀样可能是并⾏的,但是协程是在⼀个线程中所以是并发.
进程:
⼀个运⾏的程序(代码)就是⼀个进程,没有运⾏的代码叫程序,进程是系统资源分配的最⼩单位,进程拥有⾃⼰独⽴的内存空间,所以进程间数据不共享,开销⼤。
线程:
调度执⾏的最⼩单位,也叫执⾏路径,不能独⽴存在,依赖进程存在⼀个进程⾄少有⼀个线程,叫主线程,⽽多个线程共享内存(数据共享,共享全局变量),从⽽极⼤地提⾼了程序的运⾏效率。
协程:
是⼀种⽤户态的轻量级线程,协程的调度完全由⽤户控制。
协程拥有⾃⼰的寄存器上下⽂和栈。
协程调度切换时,将寄存器上下⽂和栈保存到其他地⽅,在切回来的时候,恢复先前保存的寄存器上下⽂和栈,直接操作栈则基本没有内核切换的开销,
可以不加锁的访问全局变量,所以上下⽂的切换⾮常快。
进程和线程1.进程和线程程序是什么?QQ.exe,PowerPoint.exe进程:是⼀个正在执⾏中的程序(程序启动,进⼊内存,即资源分配的基本单位)。
每⼀个进程执⾏都有⼀个执⾏顺序。
该顺序是⼀个执⾏路径,或者叫⼀个控制单元。
线程:就是进程中的⼀个独⽴的控制单元,是⽐进程更⼩的执⾏单位。
线程只是⼀种为单⼀处理器分配执⾏时间的⼿段(程序执⾏的基本单位,⽐如程序中有main线程,执⾏a=2+3,还有其他分叉的线程)程序是如何运⾏的?CPU读指令 PC(program counter存储指令地址),读数据Register,计算ALU,回写 --> 下⼀条指令线程如何进⾏调度?linux线程调度器(OS)操作系统 在APP中启动的线程是需要经过操作系统帮你在CPU上调度的,操作系统管理哪个线程扔到哪个CPU⾥⾯去,⽐如说,操作系统说下个线程该你了,操作系统就负责扔指令到PC⾥⾯去,扔数据到register⾥⾯去 在Java中,new Thread.start()这样就起了JVM线程线程切换的概念是什么?ContextSwitch CPU保存现场,执⾏新线程,恢复现场,继续执⾏原线程这样的⼀个过程 当我们执⾏T1的时候,T1的内容会装到CPU中,当我们执⾏T2的时候,T1的内容会从CPU中⼀到cache中 因此线程数量不是越多越好,如果线程特别多的时候,会把时间浪费在切换上⾯线程在控制着进程的执⾏。
⼀个进程中⾄少有⼀个线程。
线程的四个状态:运⾏,就绪,挂起,结束。
线程的作⽤:就是⽤来执⾏代码的。
2.什么是多线程? 多线程是指⼀个进程在执⾏过程中可以产⽣多个线程,这些线程可以同时存在,同时运⾏,⼀个进程可能包含了多个同时执⾏的线程。
如,迅雷下载,可以下载多个任务,就是多线程。
3.创建多线程的第⼀种⽅式:继承Thread类。
(1)定义类继承Thread类 (2)覆写Thread 类中的run()⽅法 ⽬的:将⾃定义代码存储在run⽅法,让线程运⾏。
Python中的线程与进程的区别与联系Python中的线程与进程的区别与联系随着计算机技术的不断发展,人们对于多任务处理的需求也越来越高,而在Python语言中,线程与进程是两种常见的多任务处理技术。
本篇论文将对Python中的线程与进程进行详细的介绍和分析,探讨它们之间的区别和联系。
一、线程的概念线程是指在进程之内独立执行的一个基本单位。
在同一个进程中,线程共享进程的资源,例如内存、文件句柄等。
线程是程序执行的最小单元,也就是说,一个进程可以包含多个线程。
同一个进程中的多个线程之间可以共享全局变量等进程级别的资源。
Python的线程使用threading模块实现。
在Python 3.2以前,线程的实现是依赖于底层操作系统实现的。
而在Python 3.2以后,线程的实现是基于pthread库实现的。
二、进程的概念进程是指正在运行的程序的一次执行过程。
在一个进程中,可以包含多个线程。
进程是操作系统中进行资源分配和调度的基本单位,每个进程都有自己的地址空间、数据栈、代码段等系统资源。
Python的进程使用multiprocessing模块实现。
由于Python的GIL锁的存在,使得Python的线程并发度非常低,因此Python更倾向于使用进程进行并发操作。
三、线程和进程的区别1.执行方式不同:线程在同一进程中执行,通过线程共享操作系统资源完成任务,而进程则是在独立的地址空间中执行,通过操作系统调度完成任务。
2.通信成本不同:由于线程共享操作系统资源,因此线程间通信成本相对较低,而进程间通信成本相对较高。
3.调试难度不同:由于进程独立的地址空间,因此进程间调试难度较大,而线程是在同一进程中执行,相对更容易进行调试。
4.安全性不同:进程间拥有独立的地址空间,不会互相干扰,因此安全性相对较高,而线程在同一进程中共享地址空间,可能会发生不安全操作,因此相对不够安全。
5.执行效率不同:由于线程共享进程资源,因此线程的创建和销毁比进程更快,执行效率也更高。
一:线程与进程1.概念线程:是程序执行流的最小单元,是系统独立调度和分配CPU (独立运行)的基本单位。
【操作系统技术中的术语,是操作系统能够进行运算调度的最小单位,它被包涵在进程之中,是行程中的实际运作单位。
一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并行多个线程,每条线程并行执行不同的任务。
在Unix System及SunOS中也被称为轻量进程(lightweight processes),但轻量进程更多指内核线程(kernel thread),而把用户线程称为线程。
计算机科学术语,指运行中的程序的调度单位。
】主要特点【在多线程OS中,通常是在一个进程中包括多个线程,每个线程都是作为利用CPU的基本单位,是花费最小开销的实体。
线程具有以下属性。
1)轻型实体线程中的实体基本上不拥有系统资源,只是有一点必不可少的、能保证独立运行的资源,比如,在每个线程中都应具有一个用于控制线程运行的线程控制块TCB,用于指示被执行指令序列的程序计数器、保留局部变量、少数状态参数和返回地址等的一组寄存器和堆栈。
2)独立调度和分派的基本单位。
在多线程OS中,线程是能独立运行的基本单位,因而也是独立调度和分派的基本单位。
由于线程很“轻”,故线程的切换非常迅速且开销小。
3)可并发执行。
在一个进程中的多个线程之间,可以并发执行,甚至允许在一个进程中所有线程都能并发执行;同样,不同进程中的线程也能并发执行。
4)共享进程资源。
在同一进程中的各个线程,都可以共享该进程所拥有的资源,这首先表现在:所有线程都具有相同的地址空间(进程的地址空间),这意味着,线程可以访问该地址空间的每一个虚地址;此外,还可以访问进程所拥有的已打开文件、定时器、信号量机构等。
】线程的五大状态【线程从创建、运行到结束总是处于下面五个状态之一:新建状态、就绪状态、运行状态、阻塞状态及死亡状态。
1.新建状态(New):当用new操作符创建一个线程时,例如new Thread(r),线程还没有开始运行,此时线程处在新建状态。
鱼还是熊掌:浅谈多进程多线程的选择
关于多进程和多线程,教科书上最经典的一句话是“进程是资源分配的最小单位,线程是CPU调度的最小单位”,这句话应付考试基本上够了,但如果在工作中遇到类似的选择问题,那就没有这么简单了,选的不好,会让你深受其害。
经常在网络上看到有的XDJM问“多进程好还是多线程好?”、“Linux下用多进程还是多线程?”等等期望一劳永逸的问题,我只能说:没有最好,只有更好。
根据实际情况来判断,哪个更加合适就是哪个好。
我们按照多个不同的维度,来看看多线程和多进程的对比(注:因为是感性的比较,因此都是相对的,不是说一个好得不得了,另外一个差的无法忍受)
看起来比较简单,优势对比上是“线程 3.5 v 2.5 进程”,我们只管选线程就是了?
呵呵,有这么简单我就不用在这里浪费口舌了,还是那句话,没有绝对的好与坏,只有哪个更加合适的问题。
我们来看实际应用中究竟如何判断更加合适。
1)需要频繁创建销毁的优先用线程
原因请看上面的对比。
这种原则最常见的应用就是Web服务器了,来一个连接建立一个线程,断了就销毁线程,要是用进程,创建和销毁的代价是很难承受的
2)需要进行大量计算的优先使用线程
所谓大量计算,当然就是要耗费很多CPU,切换频繁了,这种情况下线程是最合适的。
这种原则最常见的是图像处理、算法处理。
3)强相关的处理用线程,弱相关的处理用进程
什么叫强相关、弱相关?理论上很难定义,给个简单的例子就明白了。
一般的Server需要完成如下任务:消息收发、消息处理。
“消息收发”和“消息处理”就是弱相关的任务,而“消息处理”里面可能又分为“消息解码”、“业务处理”,这两个任务相对来说相关性就要强多了。
因此“消息收发”和“消息处理”可以分进程设计,“消息解码”、“业务处理”可以分线程设计。
当然这种划分方式不是一成不变的,也可以根据实际情况进行调整。
4)可能要扩展到多机分布的用进程,多核分布的用线程
原因请看上面对比。
5)都满足需求的情况下,用你最熟悉、最拿手的方式
至于“数据共享、同步”、“编程、调试”、“可靠性”这几个维度的所谓的“复杂、简单”应该怎么取舍,我只能说:没有明确的选择方法。
但我可以告诉你一个选择原则:如果多进程和多线程都能够满足要求,那么选择你最熟悉、最拿手的那个。
需要提醒的是:虽然我给了这么多的选择原则,但实际应用中基本上都是“进程+线程”的结合方式,千万不要真的陷入一种非此即彼的误区。