def func(n): ...... if __name__ == ‘__main__‘: p = Process(target=func, args = (1,)) p.start()
m = 1 def task1(t): global m # 由于m是不可变对象,所以设置全局变量 while True: sleep(t) m += 1 print(‘这是任务一。。。。。‘, os.getpid(), ‘---‘, os.getppid(), ‘m=‘, m) # getpid得到当前进程pid,getppid得到父(主)进程的pid def task2(t): global m while True: sleep(t) m += 1 print(‘这是任务二。。。。。‘, os.getpid(), ‘---‘, os.getppid(), ‘m=‘, m) # 子进程的ppid和父(主)进程的pid一致 n = 1 if __name__ == ‘__main__‘: p1 = Process(target=task1, name=‘任务1‘, args=(0.1,)) # 创建子进程 p2 = Process(target=task2, name=‘任务2‘, args=(0.2,)) p1.start() # 开启一个进程,并执行run方法 ps:run():执行进程 p2.start() print(os.getpid()) # 主进程的pid print(p1.name) print(p2.name) # 主进程,先运行主进程,无论主进程在那个位置 for i in range(5): n += 1 m += 1 sleep(0.2) print(‘主进程n={},m={}‘.format(n, m)) else: p1.terminate() p2.terminate() print(‘-end-‘) ‘‘‘ 运行结果: 1376 任务1 任务2 这是任务一。。。。。 14636 --- 1376 m= 2 主进程n=2,m=2 这是任务一。。。。。 14636 --- 1376 m= 3 这是任务二。。。。。 7912 --- 1376 m= 2 这是任务一。。。。。 14636 --- 1376 m= 4 主进程n=3,m=3 这是任务二。。。。。 7912 --- 1376 m= 3 这是任务一。。。。。 14636 --- 1376 m= 5 这是任务一。。。。。 14636 --- 1376 m= 6 主进程n=4,m=4 这是任务二。。。。。 7912 --- 1376 m= 4 这是任务一。。。。。 14636 --- 1376 m= 7 这是任务一。。。。。 14636 --- 1376 m= 8 主进程n=5,m=5 这是任务二。。。。。 7912 --- 1376 m= 5 这是任务一。。。。。 14636 --- 1376 m= 9 这是任务一。。。。。 14636 --- 1376 m= 10 主进程n=6,m=6 -end- ‘‘‘
由此可见,父进程是先运行的(与位置无关),两个子进程是同时运行的。在这里,每个进程的进程id是始终不变的
对于全局变量m,每个进程访问时,都会有一个独立的m出现。各个进程可以独立运行,互不影响。所以进程之间不能用这种方式(全局变量)通信
大概就是下图这样:
class MyProcess(Process): def __init__(self, n): super(MyProcess, self).__init__() self.n = n def run(self): ...... if __name__ == ‘__main__‘: p = MyProcess(args = (1,)) p.start()
主要是重新定义run方法
def task(n): ...... def back(n): ...... if __name__ == ‘__main__‘: p = Pool(5) lis = [...] for i in lis: # p.apply(target=task, args=(i,)) # 阻塞式 p.apply_async(target=task, args=(i,), callback=back) # 非阻塞式,callbacka将target的返回结果传给back pool.close() # 添加任务结束 pool.join() # 插在主进程前,执行完才可以执行主进程
非阻塞式:全部添加到队列中,立刻返回,没有等待其他进程完成之后才结束(最大化利用cpu)
阻塞式:添加一个执行一个,若一个任务不结束,另一个任务就进不到cpu
利用队列(Queue)
def a(q): ...... q.put(...) ...... def b(q): while not q.empty(): ....... q.get() ...... if __name__ == ‘__main__‘: q = Queue(5) p1 = Process(target=a, args=(q,)) p2 = Process(target=b, args=(q,)) try: p1.start() p1.join() # 进程会同时开始,这样p2就会用空队列开始执行, p2.start() except: print(‘发成错误‘)
ps:1.队列没有put进值的时候,使用get方法会出现阻塞 2.超出队列长度,会出现阻塞
q = Queue(2) # print(q.get()) # 在put之前使用get,会发生阻塞 q.put(1) q.put(2) # q.put(2) # 超出队列长度会发生阻塞 print(q.get())
关于if __name__ == ‘__main__‘:
用来识别当前要执行的代码、方法的所属。执行本文件的方法、代码;避免其他文件引入(import)的方法、代码被执行
原文:https://www.cnblogs.com/xiaoqichaoren/p/12263567.html