Python 的多线程和并行

作者: , 共 1970 字 , 共阅读 0

1、另起线程

核心就是threading.Thread

from threading import Thread

def square(x):
    print(x * x)

def mul(x, y):
    print(x * y)

if __name__ == "__main__":
    thread1 = Thread(target=square, args=(10, ))
    thread2 = Thread(target=mul, args=(10, 10))

    thread1.start()
    thread2.start()

    thread1.join()
    thread2.join()

注意:

  • 必须调用start,线程才会被启动。
  • join会将线程合并到当前线程,当前线程被阻塞,直到合并的线程执行完毕。若不合并,主线程退出后,新起的线程将自动退出。

2、多进程并行任务

核心就是multiprocessing.Pool.mapmultiprocessing.Pool.starmap

2.1、单参数函数

Pool.map用起来简单顺手,两行代码就可以并行执行多任务:

from multiprocessing import Pool

def square(x):
    return x * x

if __name__ == "__main__":
    with Pool() as pool:
        res = pool.map(square, range(10))

        print(res)  

2.2、绑定多参数函数的多余参数

如果函数有多个参数,然后只遍历其中一个参数,一个直观的想法是:

from multiprocessing import Pool

def mul(x, y):
    return x * y

if __name__ == "__main__":
    double = lambda x: mul(x, 2)

    with Pool() as pool:
        print(pool.map(double, range(10)))

可惜这个方法行不通,会报pickle序列化错误:

_pickle.PicklingError: Can't pickle <function <lambda> at 0x7f9d3e447f70>: attribute lookup <lambda> on __main__ failed

一个解决办法是使用functools.partial,也就多一行代码:

from multiprocessing import Pool
from functools import partial

def mul(x, y):
    return x * y


if __name__ == "__main__":
    double = partial(mul, y=2)

    with Pool() as pool:
        print(pool.map(double, range(10)))

2.3、多参数函数

并行执行多参数函数需要联合使用starmapzip

from multiprocessing import Pool

def mul(x, y):
    return x * y

if __name__ == "__main__":
    with Pool() as pool:
        print(pool.starmap(mul, zip(range(10), range(10)))

2.4、并行计算任意任务

上面三种都是并行执行同样的函数(作用于多个参数)。如果要并行执行任意任务,参考下面例子,也就几行代码:

from multiprocessing import Pool

def mul(x, y):
    return x * y

if __name__ == "__main__":
    with Pool() as pool:
        res = []
        for i in range(10):
            res.append(pool.async_apply(mul, (i, i)))
        print([r.get() for r in res])

Q. E. D.

类似文章:
std::thread是 C++ 11 新引入的标准线程库。在同样是 C++ 11 新引入的 lambda 函数的辅助下,std::thread用起来特别方便:
编程 » Python
今天写一段程序时遇到一个问题,查了好一会才搞清楚。代码可以简化为下面这个小代码:
相似度: 0.121
以下对并行计算的个人理解受到较多质疑,删除之。
编程 » C++, 异步
C++11 的标准异步库至少包含下面内容:
编程 » C++
有两种方法,一种在线程的调用函数内部设置,还有一种是在外部对指定线程变量做设置。
编程 » Matlab, 并行计算
我们知道 Matlab 不支持多重 parfor 循环。下面代码会出错:
编程 » Python
在 Python 中,有时候为了获取当前运行的脚本的同目录下的另外一个文件,会这么写:
编程 » django, requests, python
这里的 requests 是指 Python 的 requests 包。
Python 提供很多语法糖,用起来非常方便。@dataclass 就是其中之一。
编程 » Python
Python 在搜索模块时,依次搜索sys.path里的位置,直到找到模块为止。下面命令可以查看当前的搜索路径:
黄花城水长城离箭扣和慕田峪不远,爬升高度很小,也不长,属于最休闲级别的长城游。景区内走一圈大约五公里,爬升 200 米左右。
几周前爬箭扣,用 GT2 手表,在登山模式下记录的爬升高度严重异常,爬升高度高达 978 米。但手机上用专用户外 APP (两步路)记录的爬升只有 610 米。