进程相关概念、开启子进程方式、给子进程传参
进程:是计算机中最小的资源分配单位
进程的三状态:就绪 运行 阻塞
同步异步:
同步:一件事情与另一件事情有一定的顺序
异步:两件事情可以同时进行
并行和并发
并行:在一个时间点上,有多个进程在被cpu计算
并发:在一个时间段上,有多个进程在被cpu计算
阻塞和非阻塞
阻塞:input sleep recv accept recvfrom
非阻塞:不需要等待就可以直接完成的事情
进程
如何在Python代码中启动一个进程(实现异步)
这里要用到 multiprocessing 模块
进程模块:启动进程、基础的进程信息的获取、管理
进程的同步
进程之间的数据共享
进程之间的通信
进程池
# multiprocessing 跟进程相关的基本都在这个模块里 import time def func(): time.sleep(1) print(666) func() time.sleep(1) print(777) from multiprocessing import Process import time def func(): time.sleep(1) print(666) if __name__ == "__main__": Process(target=func).start() # 开启了一个新的进程,在这个新的进程里执行的 func() time.sleep(1) print(777) # 主进程 # 777 # 666 # 运行结果仔细观察发现有异步的效果
import time import os from multiprocessing import Process def func(): time.sleep(1) print(666, os.getpid(), os.getppid()) if __name__ == "__main__": p = Process(target=func) # 这里并不代表开启了子进程 p.start() # 开启了一个子进程,并执行func() time.sleep(1) print(777, os.getpid(), os.getppid()) # 777 12340 1636 # 主进程运行的结果 # 666 7604 12340 # 子进程运行的结果 # 由上面两行结果可以得出: # 利用os.getpid()证明两个进程不一样 # 另外每次运行,os.getpid()结果都不一样 # 但是,12340是主进程的id,7604是子进程的id,1636是Pycharm的id,排列特点不变 # 几个概念: # 父进程与子进程—— # 比如运行本文件,就是父进程 # 运行Process(target=func).start()就是子进程 # 主进程——一般直接执行的那个程序就是主进程 # 为什么要有 if __name__ == "__main__" # windows操作系统开启子进程的方式问题
# 如何开启多个子进程 import time import os from multiprocessing import Process def func(): time.sleep(3) print(666, os.getpid(), os.getppid()) if __name__ == "__main__": for i in range(10): p = Process(target=func) p.start() # time.sleep(1) print(777, os.getpid(), os.getppid()) # 这里需要注意一点:Python程序一直都是逐行执行 # 但是因为这里设置了时间延迟,因此会先执行主程序的代码 # 777 6232 8396 # 666 13220 6232 # 666 14076 6232 # 666 9720 6232 # 666 12036 6232 # 666 1080 6232 # 666 3428 6232 # 666 1768 6232 # 666 11816 6232 # 666 2552 6232 # 666 13124 6232 # 观察结果发现主进程只运行了一次 # 然后剩下的全是一个子进程重新运行的结果 # 主进程运行完不会结束,它会等子进程全部运行结束 # 注意变量p拿到的是最后一个子进程的id
# 如何开启多个不同的子进程 # 这里也一样,程序是逐行解释,逐行执行 import time import os from multiprocessing import Process def func(): time.sleep(2) print(666, os.getpid(), os.getppid()) def func2(): print(111) if __name__ == "__main__": for i in range(3): p = Process(target=func) p.start() for i in range(2): p = Process(target=func2) p.start() time.sleep(1) print(777, os.getpid(), os.getppid()) # 111 # 111 # 777 3784 8396 # 666 4776 3784 # 666 10724 3784 # 666 12692 3784
# 如何给子进程传参数 from multiprocessing import Process def func(name): print(666, name) if __name__ == "__main__": p = Process(target=func,args=(777,)) # 注意是一个元组 p.start() import time from multiprocessing import Process def func(num, name): time.sleep(1) print(num, "hello", name) if __name__ == "__main__": for i in range(10): p = Process(target=func, args=(i, "abc")) p.start() print("主进程") # 主进程 # 0 hello abc # 1 hello abc # 3 hello abc # 4 hello abc # 2 hello abc # 6 hello abc # 7 hello abc # 5 hello abc # 8 hello abc # 9 hello abc # 注意子进程并不是完全按顺序运行的 # 子进程可以有返回值吗? # 不能有返回值 # 因为子进程函数中的返回值无法传递给父进程 import time from multiprocessing import Process def wahaha(): time.sleep(3) print("这是子进程,3s后才运行") if __name__ == "__main__": Process(target=wahaha).start() print("主进程") # 主进程 # 这是子进程,3s后才运行 # 主进程会默认等待子进程结束之后才结束 # 因为父进程要负责回收子进程占用的操作系统资源