进程与线程的关系
#!/usr/bin/env python# -*- coding;utf-8 -*-"""多进程(主进程,子进程): 优点:能同时利用多个CPU,进行多个操作,提高效率。 缺点:耗费内存资源(进程要开辟内存空间),进程不是越多越好,CPU个数 = 进程个数。 注意:进程创建内存空间,线程共享内存空间,进程里有全局解释器锁,进程中一次只应许一个线程被处理。 使用场景:计算密集型适合多进程。多线程(主线程,子线程): 优点:共享内存,IO操作时(不用CPU),创造并发操作(多个操作同时进行),提高效率。 缺点:抢占资源,请求上下文切换非常耗时(线程处理切换后找到上次处理的地方),线程不是越多越好,视具体案例而定。 注意:在计算机中,执行任务的最小单元就是线程。 使用场景:IO密集型适合多线程。""""""使用进程 1、创建进程"""import multiprocessingdef f1(a1): print(a1)if __name__ == "__main__": t1 = multiprocessing.Process(target=f1, args=(11,)) # t1.daemon = True t1.start() t1.join(2) t2 = multiprocessing.Process(target=f1, args=(22,)) # t2.daemon = True t2.start()
进程池:
- 进程池1
#!/usr/bin/env python# -*- coding;utf-8 -*-""" 调用Pool进程池模块,创建进程池"""from multiprocessing import Poolimport timedef myfun(i): time.sleep(2) return i + 100def end_call(arg): print("end_all", arg)if __name__ == "__main__": p = Pool(5) for i in range(10): p.apply_async(func=myfun, args=(i,), callback=end_call) print("end") p.close() p.join()
- 进程池2
#!/usr/bin/env python# -*- coding;utf-8 -*-""" apply与apply_sync的区别"""from multiprocessing import Poolimport timedef f1(a): time.sleep(1) print(a) return adef f2(b): r = "第" + str(b+1) + "个子进程执行完毕" print(r)if __name__ == "__main__": pool = Pool(5) for i in range(10): # pool.apply(func=f1, args=(i,)) pool.apply_async(func=f1, args=(i,), callback=f2) """ pool.apply:每个进程之间是串行执行的,排队执行;每一个进程都有一个join()方法 pool.apply_sync:每个进程是并发执行的,并发数取决于进程池,并且可以触发回调函数;每一个进程没有一个join()方法;每一个进程的daemon = True """ print("主进程执行完毕") pool.close() # 等所有任务终止再结束,能拿到子进程的结果 # pool.terminate() # 立即终止所有任务,拿不到子进程的结果 pool.join()
进程数据共享:
- 进程数据共享1
#!/usr/bin/env python# -*- coding;utf-8 -*-""" 默认情况下进程数据不共享,要用一个中介数据类型实现进程数据共享 进程数据共享方式一: 使用数组,Array使用时必须先定义大小 temp = Array("i",[11,22,33,44]),"i"表示数据类型,数组中的数据类型必须一致"""from multiprocessing import Process, Value, Arraydef f(n, a): n.Value = 3.1415927 for i in range(len(a)): a[i] = -a[i]if __name__ == "__main__": num = Value("d", 0.0) arr = Array("i", range(10)) p = Process(target=f, args=(num, arr)) a = Process(target=f, args=(num, arr)) p.start() a.start() p.join() a.join() print(num.value) print(arr[:])
- 进程数据共享2
#!/usr/bin/env python# -*- coding;utf-8 -*-""" 默认情况下进程数据不共享,要用一个中介数据类型实现进程数据共享 进程数据共享方式二: 使用特殊字典 dic = manager.dict()"""from multiprocessing import Process, Managerdef f(d, l): d[1] = "1" d["2"] = 2 d[0.25] = None l.reverse()if __name__ == "__main__": with Manager() as manager: d = manager.dict() l = manager.list(range(10)) p = Process(target=f, args=(d, l)) p.start() p.join() print(d) print(l)
- 进程数据不共享
#!/usr/bin/env python# -*- coding;utf-8 -*-""" 默认情况下进程数据不共享"""from multiprocessing import Processli = []def foo(i): li.append(i) print("hello", li)if __name__ == "__main__": for i in range(10): t = Process(target=foo, args=(i,)) t.start()
- 进程字典
#!/usr/bin/env python# -*- coding;utf-8 -*-"""进程数据共享方式二: 使用特殊字典dic = manager.dict()"""from multiprocessing import Process, Managerdef foo(i, dic): dic[i] = 100 + i print(len(dic))if __name__ == "__main__": manage = Manager() dic = manage.dict() # dic = dict() 数据无法共享 for i in range(2): p = Process(target=foo, args=(i, dic)) p.start() p.join()
- 进程数组
#!/usr/bin/env python# -*- coding;utf-8 -*-"""进程数据共享方式一: 使用数组,Array使用时必须先定义大小 temp = Array("i",[11,22,33,44]),"i"表示数据类型,数组中的数据类型必须一致"""from multiprocessing import Process, Arraydef foo(i, temp): print(id(temp)) temp[i] = 100 + i for item in temp: print(i, "------>>", item)if __name__ == "__main__": temp = Array("i", [11, 22, 33, 44]) for i in range(2): p = Process(target=foo, args=(i, temp)) p.start() p.join()