Python 多进程多线程的简易教程

前言

自从用了Python的多进程、多线程之后,发现了一些坑,感觉这个东西用起来还是没那么的方便呀~这里记录下我的一些简单的使用教程。

Python

在Python中,存在多进程、多线程和协程,这里就介绍多进程和多线程的使用。

这里使用的库是multiprocessing的多进程库Pool,以及multiprocessing.dummy的多线程库Pool。这两个库的方法调用都是一致的,下面将介绍下。

方法 说明
map(self, func, iterable, chunksize=None) 同步进程池。Pool类中的map方法,与内置map函数用法基本一致,融合了map函数和apply_async()函数的功能;它会使进程阻塞直到返回结果。
apply(self, func, args=(), kwds={}) 同步进程池。该函数用于传递不定参数,按照加入进程池的顺序执行事件,每次执行完一个再执行另一个,主进程会被阻塞直到函数执行结束,无法获取返回值
map_async(self, func, iterable, chunksize=None, callback=None, error_callback=None) 异步进程池。map的异步版本。
apply_async(self, func, args=(), kwds={}, callback=None, error_callback=None) 异步进程池。异步执行,同时启动进程池中多个进程执行事件,可以获取事件返回值
  • 多进程适合在CPU 密集型操作(CPU 操作指令比较多,如位数多的浮点运算)。
  • 多线程适合在IO 密集型操作(读写数据操作较多的,比如爬虫)。

多进程

需要注意的是,这里的进程是不能共享内存的,不然需要使用pickle实现数据的序列化

缺点:不能共享内存,每一个进程都有管理一份资源,非常消耗内存。

解决方案:可以通过使用静态对象的方式来共享内存,但是只允许读,不然数据的准确性无法保证。

def multi_process():
    result = []
    pool = ProcessPool(cpu_count())
    for index in range(0, cpu_count(), 1):
        result.append(pool.apply_async(func=get_data, args=(1, 2, 3,)))
    pool.close()
    pool.join()

    # 获取回调
    for res in result:
        data1, data2, data3 = res.get()
        print(data1, data2, data3)

多线程

def multi_thread():
    pool = ThreadPool(max_thead_count_io)
    pool.map(lambda item: get_data(item[0], item[1], item[2]), [[1, 2, 3], [2, 3, 4]])
    pool.close()
    pool.join()

完整的示例

from multiprocessing import cpu_count
from multiprocessing import Pool as ProcessPool
from multiprocessing.dummy import Pool as ThreadPool

# 最大的线程池线程数量
max_thead_count_cpu = cpu_count() * 6 - 1
max_thead_count_io = cpu_count() * 2 - 1


def get_data(one, two, third):
    print(one, two, third)
    return one, two, third


def multi_process():
    """
    需要注意的是,这里的进程是不能共享内存的,不然需要使用pickle实现数据的序列化
    缺点:不能共享内存,每一个进程都有管理一份资源,非常消耗内存。
    :return:
    """
    result = []
    pool = ProcessPool(cpu_count())
    for index in range(0, cpu_count(), 1):
        result.append(pool.apply_async(func=get_data, args=(1, 2, 3,)))
    pool.close()
    pool.join()

    # 获取回调
    for res in result:
        data1, data2, data3 = res.get()
        print(data1, data2, data3)


def multi_thread():
    pool = ThreadPool(max_thead_count_io)
    pool.map(lambda item: get_data(item[0], item[1], item[2]), [[1, 2, 3], [2, 3, 4]])
    pool.close()
    pool.join()


if __name__ == '__main__':
    multi_process()
    multi_thread()

附录

  • 多线程多进程协程的区别和不同的应用场景
  • 多线程、多进程、协程、并行、并发问题的面试解析
  • Python多线程、多进程、协程

其他

  • Python的包市场:https://pypi.org/

你可能感兴趣的:(Python)