进程是操作系统分配资源的最小单元, 线程是操作系统调度的最小单元。
一个应用程序至少包括1个进程,而1个进程包括1个或多个线程,线程的尺度更小。
每个进程在执行过程中拥有独立的内存单元,而一个线程的多个线程在执行过程中共享内
multiprocess模块中的Process方法接收两个参数, 第一个是target,一般指向函数名,第二个时args,需要向函数传递的参数。对于创建的新进程,调用start()方法即可让其开始。我们可以使用os.getpid()打印出当前进程的名字。
import os import time from multiprocessing import Process from threading import Thread def long_time_task(i): print("当前进程id是{}, 任务是{}".format(os.getpid(), i)) time.sleep(2) print("执行结果为:{}".format(8 ** 20)) def main(): print("当前母进程id是:{}".format(os.getpid())) start_time = time.time() # 创建进程 p1 = Process(target=long_time_task, args=(1,)) p2 = Process(target=long_time_task, args=(2,)) # 开启进程 p1.start() p2.start() # 等待所有子进程结束主进程在结束 p1.join() p2.join() end_time = time.time() print("执行时间为:{}".format(end_time - start_time)) if __name__ == '__main__': main()对Pool对象调用join()方法会等待所有子进程执行完毕,调用join()之前必须先调用close()方法,让其不再接受新的Process了。
import os import time from multiprocessing import Process, Pool, cpu_count from threading import Thread def long_time_task(i): print("当前进程id是{}, 任务是{}".format(os.getpid(), i)) time.sleep(2) print("执行结果为:{}".format(8 ** 20)) def main(): # 打印当前电脑cpu核数 print(cpu_count()) print("当前母进程id是:{}".format(os.getpid())) start_time = time.time() # 创建进程池 p = Pool(8) for i in range(8): # 调用进程对象的apply_async方法执行任务 # 包含两个参数,第一个参数是函数名,第二个参数是传递函数的参数列表 p.apply_async(func=long_time_task, args=(i,)) # 关闭进程池 p.close() # 主进程阻塞等待子进程的退出, join方法要在close或terminate之后使用。 p.join() end_time = time.time() print("执行时间为:{}".format(end_time - start_time)) if __name__ == '__main__': main()python解释器中存在GIL(全局解释器锁), 它的作用就是保证同一时刻只有一个线程可以执行代码。由于GIL的存在,很多人认为python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。
进程之间是相互独立的,每个进程都有独立的内存,使用队列queue可以实现不同进程间的通信或数据共享
import os import time from multiprocessing import Process, Queue from threading import Thread def write(q): """进程写""" print("write的进程号:{}".format(os.getpid())) for i in ["a", "mayanan", "c"]: print("put to queue:{}".format(i)) # q对象往队列里存入数据 q.put(i) time.sleep(0.5) def read(q): """进程读""" print("read的进程号:{}".format(os.getpid())) while True: # q对象从队列里取出数据 value = q.get() print(value,"---", os.getpid()) def main(): # 父进程创建Queue对象,并传递给子进程 q = Queue() # 创建进程 pw = Process(target=write, args=(q, )) pr = Process(target=read, args=(q, )) # 开启进程 pw.start() pr.start() # 等待pw结束 pw.join() # pr进程里是死循环,无法等待其结束,只能强行终止: pr.terminate() if __name__ == '__main__': main()对CPU密集型代码(比如循环计算) - 多进程效率更高
对IO密集型代码(比如文件操作,网络爬虫) - 多线程效率更高。
