并发编程
创建进程
创建进程-带传参
from multiprocessing import Process import time def func(args): print('in func %s'%args) if __name__ == '__main__': p=Process(target=func,args=(3,)) print('in main') p.start() time.sleep(2) print('end')
创建线程
from threading import Thread def func2(args): print('in func2 %s'%args) if __name__ == '__main__': t=Thread(target=func2,args=(4,)) t.start() from threading import Thread def func(n): print('in func %s'%n) t=Thread(target=func,args=(5,)) t.setDaemon(True) #setDemon 加入将主线程设置为守护线程,那么主线程结束,不管子线程有没有结束,都会自动结束 t.start() print('主线程')
开启多个子进程
from multiprocessing import Process def func(num): print('in func %s'%num) if __name__ == '__main__': p_l=[] for i in range(10): p=Process(target=func,args=(i,)) p.start() print(p.is_alive()) #判断子进程是否在执行 p_l.append(p) for p in p_l: p.join() #join方法,阻塞,使子进程执行结束完毕,再继续执行,不是守护进程哈哈哈! print('主进程代码执行结束')
from threading import Thread import os def func(n): print('in func %s'%n) t1=Thread(target=func,args=(3,)) t2=Thread(target=func,args=(4,)) t1.start() t2.start() print('主线程pid',os.getpid(),os.getppid())
守护进程
守护子进程
from multiprocessing import Process import os,time,random def task(): print('%s is running' %os.getpid()) time.sleep(2) print('%s is done' %os.getpid()) #守护进程内无法再开启子进程,否则抛出异常 # p = Process(target=time.sleep, args=(3,)) # p.start() if __name__ == '__main__': p=Process(target=task) p.daemon = True #1、必须在p.start()之前 p.start() print('主') # 结果: # 主 # 原因是:主进程程序启动执行到p子进程,由于子进程需要开辟内存空间,由于需要耗费时间,所以主进程会首先输出“主”, # 由于主进程执行完毕,那么守护子进程p也就被干掉了,随之主进程也就退出了 如果将上一句改为 if __name__ == '__main__': p=Process(target=task) p.daemon = True #1、必须在p.start()之前 p.start() p.join() print('主') # 执行结果: # 14732 is running # # 14732 is done # 主
守护进程和非守护进程并存
from multiprocessing import Process from threading import Thread import time,os def foo(): print(123) time.sleep(1) print("end123") def bar(): print(456) time.sleep(3) print("end456") if __name__ == '__main__': p1=Process(target=foo) p2 = Process(target=bar) p1.daemon=True p1.start() p2.start() print("main-------") # 结果: # main------- # 456 # end456 # 原因如下:由于p1,p2都是子进程,需要开辟内存空间,需要耗费时间,所以会优先输出主进程“main”, # 由于p1是守护子进程,p2是非守护子进程,当主进程执行完毕(注意之类主进程还没有退出,因为还有p2非守护进程), # p1守护进程也就退了,但是还有一个p2非守护进程,所以p2会执行自己的代码任务,当p2执行完毕,那么主进程也就退出了, # 进而整个程序就退出了
守护线程
守护子线程
from multiprocessing import Process from threading import Thread import os,time,random def task(): # t=Thread(target=time.sleep,args=(3,)) # t.start() print('%s is running' %os.getpid()) time.sleep(2) print('%s is done' %os.getpid()) if __name__ == '__main__': t=Thread(target=task) t.daemon = True t.start() print('主') # 结果: # 18704 is running # 主 # 原因是: # 在执行到守护子线程t,由于主线程子线程通用一块内存,所以不存在不同进程创建各自空间, # 所以就先输出子进程的执行任务代码,所以输出print(‘%s is running’ %os.getpid()),由于time.sleep(2), # 所以就会执行主线程“main”,然后主线程执行完毕,那么即使2秒过后,由于主线程执行完毕,那么子守护线程也就退出了, # 所以 print(‘%s is done’ %os.getpid())就不会执行了。
守护子线程与非守护子线程并存
from threading import Thread import time def foo(): print(123) time.sleep(1) print("end123") def bar(): print(456) time.sleep(3) print("end456") if __name__ == '__main__': t1=Thread(target=foo) t2 = Thread(target=bar) t1.daemon=True t2.start() t1.start() print("main-------") # 结果: # 456 # 123 # main------- # end123 # end456 # # 原因是: # t1是守护子线程,t2非守护子线程,跟主线程使用一块内存,所以会输出t1,t1子线程的任务代码,所以执行456, # 123由于t1,t2都有睡眠时间,所以执行主线程代码,然后对主线程来说, # 运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕,所以会执行t1,t2睡眠后的任务代码, # 然后程序退出。 我们会问为什么t1守护子线程,也会执行sleep后的代码,不是说主线程代码执行完毕, # 守护线程就被干掉了吗?这里要注意是对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕, # 主线程才算运行完毕,当时t2还没执行完毕
开启进程池
不一次性出来结果
import os from multiprocessing import Pool import time def func(num): time.sleep(2) print('in func %s'%num) if __name__ == '__main__': p=Pool(5) for i in range(20): p.apply_async(func,args=(i,)) #apply_async表示五个一出,换成apply表示为同步出,一个一个出 p.close() p.join()
一次性出来执行结果
from multiprocessing import Pool import time def haha(num): print('in func %s'%num) return True if __name__ == '__main__': p=Pool(5) p_l=[] for i in range(20): ret=p.apply_async(func=haha,args=(i,)) #进程池使用func,开启进程使用target p_l.append(ret) for ret in p_l: print(ret.get()) #如果haha这个函数有返回值,则可通过ret.get()获取返回值,使用p_l=[]这种方式,可以去掉join,close,
等待所有的任务执行完毕再取出结果。 #join和get的区别在于:join等待所有的进程执行完毕就用join,若想提高效率,执行一个进程就出来一个结果,就用get().如果函数有返回值就用get()方法。
开启线程池
from concurrent.futures import ThreadPoolExecutor import time def sayhello(a): print("hello: "+a) time.sleep(0.1) def main(): seed=["a","b","c"] start1=time.time() for each in seed: sayhello(each) end1=time.time() print("time1: "+str(end1-start1)) start2=time.time() with ThreadPoolExecutor(3) as executor: for each in seed: executor.submit(sayhello,each) end2=time.time() print("time2: "+str(end2-start2)) start3=time.time() with ThreadPoolExecutor(3) as executor1: executor1.map(sayhello,seed) end3=time.time() print("time3: "+str(end3-start3)) if __name__ == '__main__': main()