1 # 进程: 代码+资源
2
3 """
4
5 语法结构:
6
7 1> multiprocessing 模块 Process 类
8 2> Process() 参数:
9 target:表示调用对象,即进程要执行的任务
10 args:给target指定的函数传参,以元组的形式传参
11 kwargs:字典对象传参
12 name:子进程名称,默认Process-N,N为从1开始递增的整数
13 group:指定进程组
14 pid:当前的进程号
15
16 """
17
18
19 import os
20 from multiprocessing import Process
21
22
23 def one():
24 print(f'one child process id is {os.getpid()}, parent process is {os.getppid()}')
25
26
27 def two():
28 print(f'two child process id is {os.getpid()}, parent process is {os.getppid()}')
29
30
31 if __name__ == '__main__':
32
33 p1 = Process(target=one)
34 p2 = Process(target=two)
35
36 p1.start()
37 p2.start()
38
39 p1.name = "three"
40
41 print(f'one child process id is {p1.name}, parent process is {p1.pid}')
42
43 print(f'main child process id is {os.getpid()}, parent process is {os.getppid()}')
44 #
45 # one child process id is three, parent process is 4232
46 # main child process id is 11748, parent process is 10288
47 # one child process id is 4232, parent process is 11748
48 # two child process id is 15572, parent process is 11748
49
50
51 """
52
53 1> is_alive 判断进程是否活着
54 2> join([timeout]) join(2)
55 3> terminate() 终结进程
56
57 """
58
59 from multiprocessing import Process
60
61
62 def sing(name):
63 print(f'{name} is singing')
64
65
66 def dance(name):
67 print(f'{name} is dancing')
68
69
70 if __name__ == '__main__':
71
72 p1 = Process(target=sing, args=('noise',))
73 p2 = Process(target=dance, args=('lys',))
74
75 p1.start()
76 # p1.join()
77 p2.start()
78 # p2.join()
79
80 # 此时p1,p2启动等待cpu分配资源,但是主进程继续执行
81 print(f'sing is {p1.is_alive()}')
82 print(f'dance is {p2.is_alive()}')
83
84 # sing is True
85 # dance is True
86 # noise is singing
87 # lys is dancing
88
89 # 如果想p1执行完,再执行p2,这个时候可以用join或者互斥锁
90 # noise is singing
91 # lys is dancing
92 # sing is False -> p1 已经执行完毕,自动终结
93 # dance is False -> p2 已经执行完毕,自动终结
94 from multiprocessing import Process
95
96 import time
97
98 list1 = []
99
100
101 def funa():
102 for i in range(3):
103 list1.append(i)
104 time.sleep(1)
105 print(f'funa 的{list1}')
106
107
108 def funb():
109 print('funb 的{}'.format(list1))
110
111
112 if __name__ == '__main__':
113
114 p1 = Process(target=funa)
115 p2 = Process(target=funb)
116
117 p1.start()
118 p1.join()
119 p2.start()
120
121 #
122 # funa 的[0]
123 # funa 的[0, 1]
124 # funa 的[0, 1, 2]
125 # funb 的[]
126
127
128 """
129 队列的基本操作:
130 1》 入队:将一个数据放到队列尾部
131 2》 出队:从队列的头部取出一个元素
132 支持队尾插入元素,在队头删除元素
133 Queue([maxsize] ) maxsize 小于或等于0,队列大小没有限制
134 队列常用方法
135 q = Queue() 初始化队列对象
136 q.empty() 判断是否为空,为空则为True
137 q.get() 取值
138 q.put() 赋值
139 q.full() 判断队列是否满了
140 q.qsize() 返回队列大小
141
142 """
143
144 #
145 # from queue import Queue
146
147 # q = Queue(3)
148 # q.put('msg1')
149 # q.put('msg2')
150 # print(q.full())
151 # q.put('msg3')
152 # print(q.full())
153 # print(q.qsize())
154 # print(q.get())
155
156
157 from multiprocessing import Process,Queue
158
159 import time
160
161
162
163 def funa(q1):
164 for i in range(3):
165 q1.put(i)
166 time.sleep(1)
167 print("funa 的{}".format(i))
168
169
170 def funb(q1):
171
172 while True:
173 if not q1.empty():
174 print('funb 的{}'.format(q1.get()))
175 else:
176 break
177
178
179 if __name__ == '__main__':
180
181 q1 = Queue(3)
182 p1 = Process(target=funa, args=(q1,))
183 p2 = Process(target=funb, args=(q1,))
184
185 p1.start()
186 p1.join()
187 p2.start()
188 print("this is main program")
189
190
191 # funa 的0
192 # funa 的1
193 # funa 的2
194 # this is main program
195 # funb 的0
196 # funb 的1
197 # funb 的2
198
199
200
201
202
203
204
205
206
207
208
209
210
211 """
212 p.apply_async(func,args,kwds) 异步非阻塞
213 p.close() 关闭进程池
214 terminate() 中止
215 join() 阻塞
216
217
218 进程池使用场景
219 1> 利用python 进行系统管理时,同时操作多个文件目录或远程控制多台主机,并行操作可以节约大量时间,
220 2> 提交任务的两种方式:
221 同步调用:提交完任务后,在原地等待,知道任务完成后,拿到返回值,才继续下一行代码
222 异步调用:提交完任务后,不在原地等待,直接执行下一行代码
223
224 """
225
226
227 # 异步举例
228 import os, time
229
230 from multiprocessing import Pool
231
232
233 def learn(n, x):
234 print('we are studying now at {}-{}'.format(os.getpid(), os.getppid()))
235 time.sleep(1)
236 x = x + 1
237 return n*2, x
238
239
240 if __name__ == '__main__':
241
242 p = Pool(4)
243 list1 = []
244 for i in range(6):
245 # result = p.apply_async(learn, args=(2, 0,)) # 异步
246 result = p.apply(learn, args=(2, 0,)) # 同步
247 print(result)
248 list1.append(result)
249
250 p.close()
251 p.join()
252
253 for j in list1:
254 print(j) # 同步不需要
255 # print(j.get()) # 异步通过get取值
256
257 """
258 异步=========================
259 根据Pool的进程数量,我们能得知os.getpid() 能有几个进程数
260 根据循环次数,能够知道做几次调用,并且返回值必须通过get获得,否则为地址
261 <multiprocessing.pool.ApplyResult object at 0x000001828A13DBC8>
262 <multiprocessing.pool.ApplyResult object at 0x000001828A13DCC8>
263 <multiprocessing.pool.ApplyResult object at 0x000001828A13DDC8>
264 <multiprocessing.pool.ApplyResult object at 0x000001828A13DE88>
265 <multiprocessing.pool.ApplyResult object at 0x000001828A13DF08>
266 <multiprocessing.pool.ApplyResult object at 0x000001828A142048>
267 we are studying now at 16360-10252
268 we are studying now at 13772-10252
269 we are studying now at 11132-10252
270 we are studying now at 13820-10252
271 we are studying now at 16360-10252
272 we are studying now at 13772-10252
273 (4, 1)
274 (4, 1)
275 (4, 1)
276 (4, 1)
277 (4, 1)
278 (4, 1)
279 同步=======================
280 we are studying now at 16940-13756
281 (4, 1)
282 we are studying now at 16864-13756
283 (4, 1)
284 we are studying now at 16796-13756
285 (4, 1)
286 we are studying now at 16920-13756
287 (4, 1)
288 we are studying now at 16940-13756
289 (4, 1)
290 we are studying now at 16864-13756
291 (4, 1)
292 (4, 1)
293 (4, 1)
294 (4, 1)
295 (4, 1)
296 (4, 1)
297 (4, 1)
298 """