一.线程、进程
1.简述
- 进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,通俗讲就是自定义一段程序的执行过程,即一个正在运行的程序。线程是进程的基本单位,又称为轻量级进程。 * 不同的进程在内存中会开辟独立的地址空间,默认进程之间的数据是不共享,线程是由进程创建,所以处在同一个进程中的所有线程都可以访问该进程所包含的地址空间,当然也包含存储在该空间中的所有资源。
-
应用场景:
IO密集型操作由于不占用CPU资源,所以一般使用线程来完成
计算密集型操作靠cpu,所以一般使用进程来完成 -
为什么使用多线程或多进程?
多线程和多进程可以提供程序的并发处理能力。看下面需求:
现在有10台主机,现在需要监控主机的存过状态,默认使用单线程,如下:
import time st = time.time() #程序开始时间 def f1(arg): time.sleep(2) #假设ping一次需要2s print("ping %s主机中..." % arg) host_List = [0,1,2,3,4,5,6,7,8,9,] #假设列表中1233。。表示10个主机 for i in host_List: f1(i) cost_time = time.time() - st print('程序耗时:%s' % cost_time)
程序运行结果:
ping 0主机中...
ping 1主机中...
ping 2主机中...
ping 3主机中...
ping 4主机中...
ping 5主机中...
ping 6主机中...
ping 7主机中...
ping 8主机中...
ping 9主机中...
程序耗时:20.002294063568115
发现耗时20s,这仅仅是10台机器,如果100台呢,效率会非常低。假如用了多线程呢?
import threading import time st = time.time() #程序开始时间 def f1(arg): time.sleep(2) #假设ping一次需要2s print("ping %s主机中..." % arg) host_List = [0,1,2,3,4,5,6,7,8,9,] #假设列表中1233。。表示10个主机 for i in host_List: t = threading.Thread(target=f1, args=(i,)) t.start() t.join() cost_time = time.time() - st print('程序耗时:%s' % cost_time)
运行结果:
ping 0主机中...
ping 1主机中...
ping 5主机中...
ping 4主机中...
ping 2主机中...
ping 3主机中...
ping 7主机中...
ping 6主机中...
ping 8主机中...
ping 9主机中...
程序耗时:2.002915382385254
从结果中看出,10个机器启用10个线程并发去独立ping,这样耗时仅仅是单线程的耗时,效率大大提供。所以多进程多线程一般用来提高并发
2.线程进程的基本操作
创建
-
线程
- 创建方法
import threading import time def f1(args): time.sleep(2) print(args) #方式1 直接使用thread模块进行创建 for i in range(10): t = threading.Thread(target=f1,args=(123,)) #target是要执行的任务(函数),args是任务(函数)的参数 t.start() #方式2 使用自定义类创建 class Mythread(threading.Thread): def __init__(self,func,args): self.func = func self.args = args super(Mythread,self).__init__() def run(self): self.func(self.args) obj = Mythread(f1,123) obj.start()
上述代码创建了10个“前台”线程,然后控制器就交给了CPU,CPU根据指定算法进行调度,分片执行指令
-
线程的其他方法
- start 线程准备就绪
- setName 为线程设置名称
- getName 获取线程名称
- setDaemon 设置为后台线程或前台线程(默认),注意需要设置在start前 如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,均停止 如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止
- join 放在for循环内表示逐个执行每个线程,执行完毕后继续往下执行,该方法使得多线程变得无意义,放在for循环外,会阻塞主进程,这样主进程会等待线程执行完之后,再去继续执行下面的代码
- run 线程被cpu调度后自动执行线程对象的run方法,这也是线程第二种创建方法的原理
-
方法具体使用
-
使用setDaemon
默认不使用setDaemon 情况
前台进程import threading import time def f1(args): time.sleep(2) print(args) print('-----start------') for i in range(10): t = threading.Thread(target=f1,args=(123,)) t.setDaemon(False) #默认为false 主线程等待子线程执行完之后再退出程序 t.start() print('-------end------') 执行效果: -----start------ -------end------ end主线程执行完毕,等待子线程执行 123 子线程执行结果 123 123 123 123 123 123 123 123 123
-