Python中多进程的基本操作

Python中的多进程可以使用到多颗CPU带来的好处,在前面多线程中已经总结出,对于IO密集型的操作,由于IO不占用CPU,所以使用轻量级的多线程即可解决问题;而对于计算密集型操作,由于多线程不支持使用多颗CPU,所以使用多进程是最合适的。本篇文件就介绍Python多进程的使用

创建一个子进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import multiprocessing
import time


def worker(arg):
time.sleep(2)
print(arg)

if __name__ == '__main__':
p = multiprocessing.Process(target=worker, args=("Hello PolarSnow",))
p.start()
print("p.pid:", p.pid)
print("p.name", p.name)
print("p.is_alive:", p.is_alive())

------------
p.pid: 17731
p.name Process-1
p.is_alive: True
Hello PolarSnow

如果你看过前面多线程的文章,可以看出,多进程的基本用法和多线程很相似

多个进程处理同一个函数

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
import multiprocessing
import time


def worker(arg):
time.sleep(2)
print(arg)

if __name__ == '__main__':
for i in range(5):
p = multiprocessing.Process(target=worker, args=(i,))
p.start()

print("CPU数量:", str(multiprocessing.cpu_count()))

for p in multiprocessing.active_children():
print("子进程名称:", p.name, "子进程id:", p.pid)

------------
CPU数量: 4
子进程名称: Process-5 子进程id: 18705
子进程名称: Process-3 子进程id: 18703
子进程名称: Process-2 子进程id: 18702
子进程名称: Process-1 子进程id: 18701
子进程名称: Process-4 子进程id: 18704
0
1
2
3
4

多个进程处理多个函数

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
31
32
import multiprocessing
import time


def worker1(arg):
time.sleep(2)
print("worker1", arg)


def worker2(arg):
time.sleep(2)
print("worker2", arg)


def worker3(arg):
time.sleep(2)
print("worker3", arg)

if __name__ == '__main__':

p1 = multiprocessing.Process(target=worker1, args=("PS1",))
p2 = multiprocessing.Process(target=worker1, args=("PS2",))
p3 = multiprocessing.Process(target=worker1, args=("PS3",))
p1.start()
p2.start()
p3.start()

print("CPU数量:", str(multiprocessing.cpu_count()))

# 可以查看当前正在运行的子进程的信息
for p in multiprocessing.active_children():
print("子进程名称:", p.name, "子进程id:", p.pid)

daemon属性

不加daemon属性

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
31
32
33
34
import multiprocessing
import time


def worker(arg):
time.sleep(2)
print(arg)

if __name__ == '__main__':
for i in range(5):
p = multiprocessing.Process(target=worker, args=(i,))
# p.daemon = True
p.start()

print("CPU数量:", str(multiprocessing.cpu_count()))

for p in multiprocessing.active_children():
print("子进程名称:", p.name, "子进程id:", p.pid)

print("End")

------------
CPU数量: 4
子进程名称: Process-2 子进程id: 21859
子进程名称: Process-3 子进程id: 21860
子进程名称: Process-1 子进程id: 21858
子进程名称: Process-4 子进程id: 21861
子进程名称: Process-5 子进程id: 21862
End
0
1
2
3
4

加上daemon属性

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
import multiprocessing
import time


def worker(arg):
time.sleep(2)
print(arg)

if __name__ == '__main__':
for i in range(5):
p = multiprocessing.Process(target=worker, args=(i,))
p.daemon = True
p.start()

print("CPU数量:", str(multiprocessing.cpu_count()))

for p in multiprocessing.active_children():
print("子进程名称:", p.name, "子进程id:", p.pid)

print("End")

------------
CPU数量: 4
子进程名称: Process-2 子进程id: 21913
子进程名称: Process-1 子进程id: 21912
子进程名称: Process-4 子进程id: 21915
子进程名称: Process-5 子进程id: 21916
子进程名称: Process-3 子进程id: 21914
End

p.daemon的默认值为False,意为主进程等待子进程执行完毕后再退出程序

p.daemon的值为True时,意为当主进程执行完毕时,立即退出程序

join方法

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
31
32
33
import multiprocessing
import time


def worker(arg):
time.sleep(2)
print(arg)

if __name__ == '__main__':
for i in range(5):
p = multiprocessing.Process(target=worker, args=(i,))
p.daemon = True
p.start()

print("CPU数量:", str(multiprocessing.cpu_count()))

for p in multiprocessing.active_children():
print("子进程名称:", p.name, "子进程id:", p.pid)
p.join()
print("End")

------------
CPU数量: 4
子进程名称: Process-2 子进程id: 22196
子进程名称: Process-1 子进程id: 22195
子进程名称: Process-3 子进程id: 22197
子进程名称: Process-5 子进程id: 22199
子进程名称: Process-4 子进程id: 22198
0
1
2
3
End

注意:

  • join方法的作用是阻塞住主进程,让CPU无法执行join后面的代码,专注执行多线程
  • 上面演示的是多个进程对应一个join的情况,意为等待所有的子进程执行完毕后,再向下执行代码;如果join写在for循环里面,多个线程对应多个join时,意为前一个子进程执行完毕后,才能执行下一次循环,执行下一个任务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import multiprocessing
import time


def worker(arg):
time.sleep(2)
print(arg)

if __name__ == '__main__':
for i in range(5):
p = multiprocessing.Process(target=worker, args=(i,))
p.daemon = True
p.start()
p.join()

print("CPU数量:", str(multiprocessing.cpu_count()))

for p in multiprocessing.active_children():
print("子进程名称:", p.name, "子进程id:", p.pid)
# p.join()
print("End")

相当于用子进程串行执行任务

  • join是可以添加参数的,在没有参数的时候,会一直阻塞到函数执行完毕为止;设置参数后(int 时间 单位是秒)意为join最长阻塞的时间,超过这个时间后,不管子进程有没有执行完毕都会继续向下执行
1
p.join(1)

最多等待1秒(最多阻塞1秒)