[TOC=1,5] >[success] # 线程和进程 ~~~ 1.线程是操作系统能够进行运算调度的最小单位。 2.他被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中的一个单一顺序的控制流,一个进程中可以并发多个线程,每个线程并行执行不同的任务。 3.进程:要以一个整体的形式暴露给操作系统管理,里面包含对各种资源的调用,堆存的管理,网络接口调用等,对资源管理的集合就可以成为进程 4.线程:是操作系统最小的调度单位,是一串指令的集合 5.进程 要操作cpu,必须要创建一个线程~ 大白话解释: 1.电脑有固定的内存,我们可以吧应用程序理解成进程,当我们打开各种各样的应用程序的时候,我们的内存就会越来越小,这是因为进程调度内存空间, 2.不同进程占用不同的空间相互不进行干涉,可以理解成qq程序崩溃不会影响到word程序,线程在进程中,线程会跟cup进行联系调度, 3.如果qq进程中 一个线程崩溃,会导qq进程的崩溃~简单理解进程就是划分程序要用的内存,里面包含着一些线程,进程会跟cup进行运算的调度 ~~~ >[success] # 简单的使用线程 >[danger] ##### 简单使用线程 * 不使用线程 ~~~ 1.当第一个countdown(10) 执行完后执行countdown(5),是一个串行效果 ~~~ ~~~ import time def countdown(n): while n > 0: print('T-minus', n) n -= 1 time.sleep(1) countdown(10) countdown(5) 打印结果: T-minus 5 T-minus 4 T-minus 3 T-minus 2 T-minus 1 T-minus 2 T-minus 1 ~~~ * 使用线程 ~~~ 1.使用线程中有两个参数,Thread(target=, args= ),target是目标函数,args是目标函数参数,但是是元组形式 2.start 调用线程 3.这样就形成t1 和t2 并行执行 ~~~ ~~~ from threading import Thread import time def countdown(n): while n > 0: print('T-minus', n) n -= 1 time.sleep(1) t1 = Thread(target=countdown, args=(5,)) t2 = Thread(target=countdown, args=(2,)) t1.start() t2.start() 打印结果: T-minus 5 T-minus 2 T-minus 4 T-minus 1 T-minus 3 T-minus 2 T-minus 1 ~~~ >[danger] ##### 构造一个线程的继承类 ~~~ 1.通过继承线程类,重写里面的run方法,线程类中的run方法用来执行线程方法 ~~~ ~~~ import threading import time class MyTreading(threading.Thread): def __init__(self,n): super(MyTreading,self).__init__() self.n = n def run(self): print("多线程"+self.n) t1 = MyTreading("t1") t2 = MyTreading("t2") t1.start() t2.start() ~~~ >[danger] ##### 让类中的方法开启线程 ~~~ class CountdownTask: def __init__(self): self._running = True def terminate(self): self._running = False def run(self, n): while self._running and n > 0: print('T-minus', n) n -= 1 time.sleep(5) c = CountdownTask() t = Thread(target=c.run, args=(10,)) t.start() // 线程中参数共享,所以会停止线程 c.terminate() t.join() ~~~ >[danger] ##### 判断线程是否运行 --- is_alive ~~~ t = Thread(target=countdown, args=(5,)) if t.is_alive(): print('Still running') else: print('Completed') ~~~ >[danger] ##### 设置线程守护函数 --- daemon ~~~ // true 开启线程守护 t = Thread(target=countdown, args=(10,), daemon=True) ~~~ >[danger] ##### 计算线程运行时长 -- join ~~~ 1.想知道线程时长就给知道两个概念 --- 主线程和子线程2 2.主线程和 子线程就像打游戏, 主线任务和支线任务,主线任务就是这个程序从头到尾执行一遍,支线任务就是你开启的线程 ~~~ * 通过例子认识主线程和子线 ~~~ 代码测试run函数的运行时长 1.这段代码的打印结果是0.0010008811950683594 2.实际我们通过尝试推断这个代码运行时间应该时最后一个线程结束时间 5/10+0.1 3.为什么执行结果小于我们做的预期判断,是因为,这个打印结果的运行时间是,主线程 4.就像打游戏我们的主线任务就是从头跑到尾,所以这段代码实际有 5+1个线程 ~~~ ~~~ import threading import time def run(n,m): print("线程%s"%n) time.sleep(m) star_time = time.time() # 开启五个线程,每个线程运行时间成递增 for i in range(5): t1 = threading.Thread(target=run,args=(i,i/10+0.1) ) t1.start() print('主线程') print(float(time.time()-star_time)) ~~~ * 计算线程时间运行时间 join ~~~ 1.将线程连接知道最后一个线程结束才释放,也就是线程没有全部结束就不能往下执行 2.下面的案例只要子线程中第五个没结束,代码就不能往下进行,所以主线程等所有子线程结束后,在执行 ~~~ ~~~ import threading import time #创建一个保存线程的列表 list_threading = [] def run(n,m): print("线程%s"%n) time.sleep(m) star_time = time.time() for i in range(5): t1 = threading.Thread(target=run,args=(i,i/10+0.1) ) t1.start() list_threading.append(t1) #循环列表执行join for ii in list_threading: ii.join() print('主线程',star_time-time.time()) 打印结果: 线程0 线程1 线程2 线程3 线程4 主线程 -0.5024936199188232 ~~~ >[danger] ##### 打印子线程 和主线程 ~~~ import threading def run(n): print("线程%s"%n,threading.current_thread()) for i in range(5): t1 = threading.Thread(target=run ,args=(i,)) t1.start() #主线程 print(threading.current_thread()) 打印结果: 线程0 <Thread(Thread-1, started 9572)> 线程1 <Thread(Thread-2, started 7916)> 线程2 <Thread(Thread-3, started 4856)> 线程3 <Thread(Thread-4, started 5396)> 线程4 <Thread(Thread-5, started 9400)> <_MainThread(MainThread, started 3360)> ~~~ >[danger] ##### 线程守护 --- daemon ~~~ 1.当主线程结束后,开启守护的线程自动结束 2.通过运行结果发现因为是个主线程开启了守护,所以主线程结束其他线程也跟着结束 3.守护线程的生命周期在非守护线程结束时结束 ~~~ * 未开启守护线程 ~~~ 1.下面线程主线程结束了下面线程依旧还在执行 ~~~ ~~~ import threading import time def run(n): print("线程%s"%n) time.sleep(2) print("未开启守护打印线程%s"%n) for i in range(4): t1= threading.Thread(target=run,args=(i,), ) t1.start() print("主线程") 打印结果: 线程0 线程1 线程2 线程3 主线程 未开启守护打印线程3 未开启守护打印线程2 未开启守护打印线程0 未开启守护打印线程1 ~~~ * 开启守护线程 --- daemon ~~~ import threading import time def run(n): print("线程%s"%n) time.sleep(2) print("未开启守护打印线程%s"%n) for i in range(4): t1= threading.Thread(target=run,args=(i,), daemon=True) t1.start() print("主线程") 打印结果: 线程0 线程1 线程2 线程3 主线程 ~~~