# 多任务介绍 什么是多任务? 操作系统可以同时执行多个任务 现在的操作系统:windows mac linux unix 这些操作系统 都支持多任务 单核CPU如何实现多任务? 表面看,每个任务都是同时执行,实际上是每个任务在轮询着执行,只是因为CPU的调度太快,导致我们感觉像是所有任务都在同时执行 多核CPU如何实现多任务? 是真正实现了多个任务同时执行 并发:看上去一起执行,任务数大于CPU核心数 并行:一起执行,任务数必须小于等于CPU核心数 实现多任务的方式: 1、多进程方式 2、多线程方式 3、协程方式 4、多进程+多线程 ### 没有多进程 ```python import time def func(): while True: print("this is a process2") time.sleep(1.5) if __name__ == '__main__': while True: print("this is a process1") time.sleep(1) func() ``` ### multiprocessing 多进程 ```python from multiprocessing import Process import time,os def func(str): #os.getpid 获取当前进程的进程号 #os.getppid 获取当前进程的父进程 while True: print("this is process 2--%s--%s--%s"%(str,os.getpid(),os.getppid())) time.sleep(1.5) if __name__ == '__main__': print("父进程启动...--%s--%s"%(os.getpid(),os.getppid())) # 创建子进程 # target 说明进程的任务 p = Process(target=func,args=("python",)) # 启动进程 p.start() # 主进程中的 while True: print("this is a process 1--%s--%s"%(os.getpid(),os.getppid())) time.sleep(1) ``` ### 让父进程等待子进程结束之后父进程再结束 ```python from multiprocessing import Process from time import sleep def func(): print("子进程启动...") sleep(3) print("子进程结束...") if __name__ == '__main__': print("父进程启动...") p = Process(target = func) p.start() # sleep(1) # 让父进程等待子进程结束之后父进程再结束 # timeout 超时时间 父进程的等待时间 p.join() #执行后一直等待 print("父进程结束...") ``` ### 在子进程中修改全局变量 对父进程中的全局变量没有影响 ```python from multiprocessing import Process num = 100 def run1(): print("孙子进程开始...") print("孙子进程结束...%s"%(num)) def run(): print("子进程开始...") global num num += 1 print(num) p = Process(target=run1) p.start() p.join() print("子进程结束...") if __name__ == '__main__': print("父进程开始...") p = Process(target=run) p.start() p.join() num += 2 # 在子进程中修改全局变量 对父进程中的全局变量没有影响 # 我们在创建子进程的时候 对全局变量做了一个备份 # 子进程和父进程的Num是两个完全不同的变量 # 所有进程对全局变量的修改 都不会影响其它进程 print("父进程结束...%d"%(num)) ``` ### 进程池 ```python from multiprocessing import Pool,Process import time,random def foo(): print("孙子进程开始...") print("孙子进程结束...") def func(__name__): print("子进程%s启动..."%(__name__)) start = time.time() time.sleep(random.choice([1,2,3])) end = time.time() print("子进程%s结束...耗时%.2f"%(__name__,end - start)) if __name__ == '__main__': print("父进程开始...") # 创建进程池 # 如果没有参数 默认大小为自己电脑的CPU核心数 # 表示可以同时执行的进程数量 pp = Pool(2) for i in range(4): # 创建进程,放入进程池统一管理 pp.apply_async(func,args=(i,)) # 在调用join之前必须先关掉进程池 # 进程池一旦关闭 就不能再添加新的进程了 pp.close() # 进程池对象调用join,会等待进程池中所有的子进程结束之后再结束父进程 pp.join() print("父进程结束...") ``` # 多线程: 在一个进程内部,要同时干很多事,就需要同时执行多个子任务 那么我们把进程内的这些子任务叫做线程 线程的内存空间是共享的 每个线程都共享同一个进程的资源 模块: 1、_thread模块 低级模块 2、threading模块 高级模块 对_thread模块进行了封装 """ ### 创建线程 ```python import threading,time def run(num): print("子线程%s开始..."%(threading.current_thread().__name__)) time.sleep(2) print(num) time.sleep(2) # current_thread 返回一个当前线程的实例 print("子线程%s结束..."%(threading.current_thread().__name__)) if __name__ == '__main__': print("主线程%s启动..."%(threading.current_thread().__name__)) # 创建子线程 t = threading.Thread(target = run,args = (1,)) t.start() t.join() print("主线程%s结束..."%(threading.current_thread().__name__)) ``` ### 多线程共享资源 ```python import threading num = 0 var = 0 def run(n): global num for i in range(1000000): num += n num -= n def run1(n): global var for i in range(100): var += n var -= n if __name__ == '__main__': t1 = threading.Thread(target=run,args=(6,)) t2 = threading.Thread(target=run,args=(9,)) t3 = threading.Thread(target=run,args=(5,)) t3.start() t1.start() t2.start() t1.join() t2.join() t3.join() print("num = %s"%(num)) ``` ### 互斥锁 ```python import threading 创建锁对象 lock = threading.Lock() num = 0 def run(n): global num for i in range(1000000): # 加锁 为了确保下面代码只能由一个线程从头到尾的执行 # 会阻止多线程的并发执行,所以效率会大大降低 """ lock.acquire() try: num = num - n num = num + n finally: # 解锁 lock.release() """ with lock: num = num + n num = num - n if __name__ == '__main__': t1 = threading.Thread(target=run,args=(6,)) t2 = threading.Thread(target=run,args=(9,)) t1.start() t2.start() t1.join() t2.join() print("num = %s"%(num)) ```