Python - 进程管理
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 """