多任务编程-进程

速查手册

Process(group,target,name,args,kwargs)

  • group:指定进程组,目前只能使用None
  • target:执行的目标任务名
  • name:进程名字
  • args:以元组方式给执行任务传参
  • kwargs: 以字典方式给执行任务传参

Process创建的实例对象的常用方法:

  • start():启动子进程实例(创建子进程)
  • join():等待子进程执行结束
  • terminate():不管任务是否完成,立即终止子进程

Process创建的实例对象的常用属性:

name:当前进程的别名,默认为Process-N,N为从1开始递增的整数

操作方式

  1. 导入进程包

    • import multiprocessing
  2. 创建子进程并指定执行的任务

    • sub_process = multiprocessing.Process (target=任务名, name=”随便起一个名字”)
  3. 启动进程执行任务

    • sub_process.start()
  4. 获取当前进程编号

    • os.getpid()
  5. 获取当前父进程编号

    • os.getppid()
    • 获取进程编号可以查看父子进程的关系
  6. 进程执行任务并传参有两种方式:

  • 元组方式传参(args): 元组方式传参一定要和参数的顺序保持一致。
    • sub_process = multiprocessing.Process (target=任务名, args=(2,))
  • 字典方式传参(kwargs): 字典方式传参字典中的key一定要和参数名保持一致。
    • sub_process = multiprocessing.Process (target=任务名, kwargs={“count”: 5})
  1. 为了保证子进程能够正常的运行,主进程会等所有的子进程执行完成以后再销毁,设置守护主进程的目的是主进程退出子进程销毁,不让主进程再等待子进程去执行
  • 设置守护主进程方式: 子进程对象.daemon = True
  • 销毁子进程方式: 子进程对象.terminate()

Demo

进程的使用(multiprocess,target)

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

def dance():
for i in range(5):
print("跳舞中")
time.sleep(2)

def sing():
for i in range(2):
print("唱歌中")
time.sleep(2)

if __name__ == '__main__':
dance_process = multiprocessing.Process(target=dance,name="myprocess1")
sing_process = multiprocessing.Process(target=sing)

dance_process.start()
sing_process.start()

获取当前进程编号

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 time
import multiprocessing
import os # os.rename()给文件重新命名 os.getcwd()获取当前工作路径 os.chdir()修改工作路径 os.path获取当前路径

def dance():
print("dance:", os.getpid()) # 获取当前进程编号
print("dance:", multiprocessing.current_process()) # 获取当前进程
for i in range(5):
print("跳舞中")
time.sleep(0.2)


def sing():
print("sing:", os.getpid())
print("sing:", multiprocessing.current_process())
for i in range(5):
print("唱歌中")
time.sleep(0.2)


if __name__ == '__main__':
print("main:", os.getpid()) # 获取当前进程编号
print("main:", multiprocessing.current_process()) # 获取当前进程名称

sing_task = multiprocessing.Process(target=sing) # 这里一定不是调用函数
dance_task = multiprocessing.Process(target=dance, name="myprocess1")


sing_task.start()
dance_task.start()

获取当前父进程编号getppid()

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import multiprocessing
import time
import os


# 跳舞任务
def dance():
# 获取当前进程的编号
print("dance:", os.getpid())
# 获取当前进程
print("dance:", multiprocessing.current_process())
# 获取父进程的编号
print("dance的父进程编号:", os.getppid())
for i in range(5):
print("跳舞中...")
time.sleep(0.2)
# 扩展:根据进程编号杀死指定进程
os.kill(os.getpid(), 9)


# 唱歌任务
def sing():
# 获取当前进程的编号
print("sing:", os.getpid())
# 获取当前进程
print("sing:", multiprocessing.current_process())
# 获取父进程的编号
print("sing的父进程编号:", os.getppid())
for i in range(5):
print("唱歌中...")
time.sleep(0.2)


if __name__ == '__main__':

# 获取当前进程的编号
print("main:", os.getpid())
# 获取当前进程
print("main:", multiprocessing.current_process())
# 创建跳舞的子进程
# group: 表示进程组,目前只能使用None
# target: 表示执行的目标任务名(函数名、方法名)
# name: 进程名称, 默认是Process-1, .....
dance_process = multiprocessing.Process(target=dance, name="myprocess1")
sing_process = multiprocessing.Process(target=sing)

# 启动子进程执行对应的任务
dance_process.start()
sing_process.start()

进程执行带有参数的任务

  • args 表示以元组的方式给执行任务传参 kwargs 表示以字典方式给执行任务传参
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import multiprocessing
import time
import os

def process(count):
print("当前进程的编号为:", os.getpid())
print("当前进程的父进程编号为:", os.getppid())
for i in range(count):
print(f"正在执行第{i+1}次") # 等价于print("正在执行第%d次" % i)
else:
print("执行完毕")

if __name__ == '__main__':
print("主编号为:", os.getpid())

# args 表示以元组的方式给执行任务传参 kwargs 表示以字典方式给执行任务传参
#task = multiprocessing.Process(target=process,args=(5,))
task = multiprocessing.Process(target=process,kwargs={"count": 5})
task.start()

进程之间不共享全局变量

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

g_list = list() # 定义全局变量,创造一个空列表
def add_data():
for i in range(5):
g_list.append(i) # 向列表中添加元素
print(g_list)

def read_data():
print(g_list)

if __name__ == '__main__':
write_task = multiprocessing.Process(target=add_data)
read_task = multiprocessing.Process(target=read_data)

write_task.start()
write_task.join() # 主进程等待添加数据的子进程执行完成以后程序再继续往下执行,读取数据
read_task.start()

主进程会等待所有的子进程执行结束再结束

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

def task():
for i in range(5):
print("任务执行中")
time.sleep(0.4) # 休眠0.4秒

if __name__ == '__main__':
t = multiprocessing.Process(target=task)
t.start()
time.sleep(0.1)
print("over")
exit()

#执行结果表明t进程还没有执行完,就已经打印over了,这时程序不会退出要等进程结束才能退出
over
任务执行中
任务执行中
任务执行中
任务执行中
任务执行中

设置守护主进程

  • 如果不想等子进程,就要设置守护主进程

    1
    2
    3
    t.daemon = True  #设置守护主进程方式
    t.start() # 进程开始
    t.terminate() # 销毁子进程方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import multiprocessing
import time

def task():
for i in range(5):
print("任务执行中")
time.sleep(0.4) # 休眠0.4秒

if __name__ == '__main__':
t = multiprocessing.Process(target=task)
t.daemon = True
t.start()
time.sleep(0.1)
print("over")
t.terminate()
exit()