python 多线程模块 threading 及 多进程模块 multiprocessing

关于 python 多线程模块 threading 以及 多进程模块 multiprocessing 的使用。

注意:本文代码均在 python 3.5 中实现,其他版本未亲测。

threading 模块

  关于 python 的多线程模块 threading 的使用方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
def fun1():
print('thread 1 start', time.time())
for i in range(10):
time.sleep(0.5)
print('thread 1 end', time.time())

def fun2():
print('thread 2 start', time.time())
for i in range(20):
time.sleep(0.5)
print('thread 2 end', time.time())

def fun3():
print('thread 3 start', time.time())
for i in range(30):
time.sleep(0.5)
print('thread 3 end', time.time())

t1 = threading.Thread(target=fun1)
t2 = threading.Thread(target=fun2)
t3 = threading.Thread(target=fun3)

t1.start()
t1.join()
t2.start()
t3.start()
print('主线程中间', time.time())
t3.join()
t2.join()
print('主线程结束', time.time())

输出为:

thread 1 start 1526973092.5235336
thread 1 end 1526973097.535105
thread 2 start 1526973097.5354195
thread 3 start主线程中间 1526973097.5474474
1526973097.5414264
thread 2 end 1526973107.548385
thread 3 end 1526973112.5574799
主线程结束 1526973112.5574799

  可以看出,thread 1 执行完毕了后,同时开始执行(几乎) thread2, thread3 和 print 语句,(print 语句是主线程中的),这是因为,在 thread1, thread2 调用之前,t1.join() 已经阻塞了别的线程。由于 thread3 用时较长,因此 thread2 先结束,然后 thread3 结束。在 thread3 结束后,主线程才执行最后的 print 语句。

  由于 python GIL (Global Interpreter Lock) 的限制,python 的多线程并没有达到真正的多线程的效果,不能充分地利用 CPU。但是多进程可以充分地利用 CPU,因此使用 multiprocessing 模块来使用多进程。

multiprocessing 模块

  此处采用线程池的方式进行多线程操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from multiprocessing import Pool
from itertools import product

def fun(l, name, sur):
print(l + ' ' + name + ' ' + sur)

arg_1 = ['adf', 'freg', 'gr3q', 'saf', 'qrg']
arg_2 = ['sean']
arg_3 = ['tao']

if __name__ == '__main__':
pool = Pool(processes=8)
pool.starmap(func=fun, iterable=product(arg_1, arg_2, arg_3))
print('all done')

输出为:
multiprocessing 输出

以上代码为针对多参数的函数,

1
pool.starmap(func=fun, iterable=product(arg_1, arg_2, arg_3))

是通过 itertools 的 product 函数,将三个参数进行笛卡儿积。例如:

1
product(['a', 'b', 'c'], ['1']) # 结果为 ('a','1'),('b', '1'), ('c', '1')

关于 product 函数以及 itertools 包的使用,可点击这里了解更多。

值得注意的是,product 函数的输入必须是 iterable 的。这样,才可以进行 笛卡儿积。

此外,多参数进程池还有别的方法,但未亲测。
pool.map - multiple arguments

参考文章

1.https://stackoverflow.com/questions/5442910/python-multiprocessing-pool-map-for-multiple-arguments/24446525
2.


文章作者: taosean
文章链接: https://taosean.github.io/2018/05/22/python-thread/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 taosean's 学习之旅