进程和线程的选择

合集下载

进程线程练习题

进程线程练习题

进程线程练习题一、选择题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 如何选择线程

CPU 如何选择线程

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(实时操作系统)中的进程和线程是两个重要的概念,它们在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、需要更稳定安全时,适合选择进程;需要速度时,选择线程更好因为我的项⽬中需要对数据段的数据共享,可以被多个程序所修改,所以使⽤线程来完成此操作,⽆需加⼊复杂的通信机制,使⽤进程需要添加复杂的通信机制实现数据段的共享,增加了我的代码的繁琐,⽽且使⽤线程开销⼩,项⽬运⾏的速度快,效率⾼。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

鱼还是熊掌:浅谈多进程多线程的选择
关于多进程和多线程,教科书上最经典的一句话是“进程是资源分配的最小单位,线程是CPU调度的最小单位”,这句话应付考试基本上够了,但如果在工作中遇到类似的选择问题,那就没有这么简单了,选的不好,会让你深受其害。

经常在网络上看到有的XDJM问“多进程好还是多线程好?”、“Linux下用多进程还是多线程?”等等期望一劳永逸的问题,我只能说:没有最好,只有更好。

根据实际情况来判断,哪个更加合适就是哪个好。

我们按照多个不同的维度,来看看多线程和多进程的对比(注:因为是感性的比较,因此都是相对的,不是说一个好得不得了,另外一个差的无法忍受)
看起来比较简单,优势对比上是“线程 3.5 v 2.5 进程”,我们只管选线程就是了?
呵呵,有这么简单我就不用在这里浪费口舌了,还是那句话,没有绝对的好与坏,只有哪个更加合适的问题。

我们来看实际应用中究竟如何判断更加合适。

1)需要频繁创建销毁的优先用线程
原因请看上面的对比。

这种原则最常见的应用就是Web服务器了,来一个连接建立一个线程,断了就销毁线程,要是用进程,创建和销毁的代价是很难承受的
2)需要进行大量计算的优先使用线程
所谓大量计算,当然就是要耗费很多CPU,切换频繁了,这种情况下线程是最合适的。

这种原则最常见的是图像处理、算法处理。

3)强相关的处理用线程,弱相关的处理用进程
什么叫强相关、弱相关?理论上很难定义,给个简单的例子就明白了。

一般的Server需要完成如下任务:消息收发、消息处理。

“消息收发”和“消息处理”就是弱相关的任务,而“消息处理”里面可能又分为“消息解码”、“业务处理”,这两个任务相对来说相关性就要强多了。

因此“消息收发”和“消息处理”可以分进程设计,“消息解码”、“业务处理”可以分线程设计。

当然这种划分方式不是一成不变的,也可以根据实际情况进行调整。

4)可能要扩展到多机分布的用进程,多核分布的用线程
原因请看上面对比。

5)都满足需求的情况下,用你最熟悉、最拿手的方式
至于“数据共享、同步”、“编程、调试”、“可靠性”这几个维度的所谓的“复杂、简单”应该怎么取舍,我只能说:没有明确的选择方法。

但我可以告诉你一个选择原则:如果多进程和多线程都能够满足要求,那么选择你最熟悉、最拿手的那个。

需要提醒的是:虽然我给了这么多的选择原则,但实际应用中基本上都是“进程+线程”的结合方式,千万不要真的陷入一种非此即彼的误区。

相关文档
最新文档