Python 进程、进程通信 进程池

一:多进程的优点、应用场景

耗CPU计算时多进程速度大于多线程,可以最大化利用CPU计算。多进程有更强的容错性,一个进程出错不会影响其他进程。通常不需要考虑锁和同步资源的问题。

二:进程使用方法

  • 实例化 multiprocessing.Process,调用Threading的方法去进行多线程编程
  • 写子类继承 multiprocessing.Process,重写相应的方法
    说明:当程序简单时可使用实例化方法,当程序较复杂的时候,实现逻辑较多,第二种方法。
  • linux 中 os.fork() 拷贝父进程全部数据资源,fork之后的代码父子进程都会继续运行。
  • concurrent.futures 下的 ProcessPoolExecutor 就像上次的多线程那样操作,非常类似。

三: 进程间通信

  • 共享全局变量不适用多进程,多线程可以用。因为多进程的数据资源是隔离开的,相互独立无法共享变量。
  • 需要明确的是多进程间的通信和多线程不一样,不能用 queue.Queue 作为队列要用multiprocessing.Queue
  • multiprocessingQueue 不能用于 Pool ( 进程池),需要用multiprocessingManagerQueue,需要实例化:queue = Manager().Queue()
  • multiprocessingPipe:用法 recevid_pipe, send_pipe = Pipe() 只能适用于两个指定的进程。性能高于queue

四:进程的实例代码

#方法一:multiprocessing.Process
import multiprocessing
import requests

def download_html(i):
    url = f'https://www.baidu.com/s?ie=UTF-8&wd={i}'
    response = requests.get(url).text
    print(response)

ids = list(range(100))

# 方法一
for i in range(5):
    p = multiprocessing.Process(target=process, args=(i,))
    p.start()


# 方法二
def multipro_main(ids ):
    pool = multiprocessing.Pool(10)
    pool.map(download_html, ids)
    pool.close()
    pool.join()

# 方法三
from multiprocessing.dummy import   Pool as thpool
def thread_pool(ids ):
    pool = thpool(10)
    pool.map(download_html, ids)
    pool.close()
    pool.join()

# 方法四 (推荐,和多线程接口类似)
from concurrent.futures import ProcessPoolExecutor
with ProcessPoolExecutor(10) as executor:
    executor.map(download_html, ids)

五:总结

concurrent.futures 是一个非常不错的库,多线程和多进程无缝切换,非常方便。这个库设计思路也很好,为后面的写异步协程的代码也打下基础。
代码位置:github.com/rieuse/learnPython

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容