#!/usr/bin/env python # coding=utf-8 import multiprocessing import time import os ''' Python中的多线程并非真正的多线程,是利用GIL(Global Interpreter Lock)来实现的多线程,本质上仍然是单线程。 若是想利用多个CPU的资源,Python中大部分状况须要使用多进程,multiprocessing模块提供了相似于多线程的API,能够彻底利用多CPU资源。 ''' ''' https://docs.python.org/2/library/multiprocessing.html 进程类Process class multiprocessing.Process(group=None, target=None, name=None, args=(), kwargs={}) group:保留为之后所用,用None便可 target:可调用目标,会在run()中调用 name:进程名,默认为Process-# args:传入target的参数元组 kwargs:传入target的参数字典 属性: name:进程名 daemon:是否为守护进程,要在start()以前设置才有效 pid:进程ID,在进程生成以前为None exitcode:退出码,如还没终止,为None,由信号N终止,则为-N authkey:验证密钥 方法: start():开始进程,进程开始后,会自动运行run() run():进程执行任务入口 join([timeout]):父进程要等待调用join的进程结束以后才能运行,或等待timeout时间 is_alive():进程是否还活着 terminate():终止进程 ''' # 1.单进程 # 定义一个进程要运行的任务 def target_1(interval): n = 3 while n > 0: print u'时间点:{0}'.format(time.ctime()) time.sleep(interval) # 睡眠interval秒 n -= 1 def process_target_1(): p = multiprocessing.Process(target=target_1, args=(3,)) p.start() print u'进程ID:{0}'.format(p.pid) print u'进程名:{0}'.format(p.name) print u'进程活着吗?{0}'.format(p.is_alive()) p.join() # 2.多进程 def task_1(interval): print u'任务1开始\n' time.sleep(interval) print u'任务1结束\n' def task_2(interval): print u'任务2开始\n' time.sleep(interval) print u'任务2结束\n' def task_3(interval): print u'任务3开始\n' time.sleep(interval) print u'任务3结束\n' def process_multi_tasks(): p1 = multiprocessing.Process(target=task_1, args=(3,)) p2 = multiprocessing.Process(target=task_2, args=(2,)) p3 = multiprocessing.Process(target=task_3, args=(1,)) p1.start() p2.start() p3.start() print u'CPU数为:{0}'.format(multiprocessing.cpu_count()) for p in multiprocessing.active_children(): print u'子进程名:{0},ID:{1}'.format(p.name, p.pid) p1.join() p2.join() p3.join() print u'多进程任务结束' # 3.经过继承自定义进程类 class ClockProcess(multiprocessing.Process): def __init__(self, interval): multiprocessing.Process.__init__(self) self.interval = interval def run(self): # 当start()被调用,run()会被自动调用 n = 3 while n > 0: print u'时间点:{0}'.format(time.ctime()) time.sleep(self.interval) n -= 1 # 使用自定义进程类 def customized_process(): p = ClockProcess(3) p.start() # 自动调用run() p.join() # 4.使用Lock进行进程间同步,避免资源访问的冲突 def use_lock_task(lock, num): lock.acquire() # 得到锁 print u'数字:{0}'.format(num) lock.release() # 释放锁 def process_use_lock_task(): lock = multiprocessing.Lock() for num in range(10): p = multiprocessing.Process(target=use_lock_task, args=(lock, num)) p.start() p.join() # 5.使用Queue实现多进程之间数据传递,Queue是多进程安全的队列 def use_queue_write_task(q): try: q.put([1, None, 'Good'], block=False) except: pass def use_queue_read_task(q): try: print q.get(block=False) except: pass def process_use_queue(): q = multiprocessing.Queue() w = multiprocessing.Process(target=use_queue_write_task, args=(q,)) r = multiprocessing.Process(target=use_queue_read_task, args=(q,)) w.start() r.start() w.join() r.join() # 6.使用Pipe能够创建一对链接对象,俩链接对象是双工工做的 def use_pipe_task(conn): conn.send(['circle', {'cx': 5}, {'cy': 3}, {'radius': 5}]) conn.close() def process_use_pipe(): conn1, conn2 = multiprocessing.Pipe() p = multiprocessing.Process(target=use_pipe_task, args=(conn2,)) p.start() print conn1.recv() p.join() conn3, conn4 = multiprocessing.Pipe() p2 = multiprocessing.Process(target=use_pipe_task, args=(conn3,)) p2.start() print conn4.recv() p2.join() # 7.使用Value或Array共享资源,共享的对象是进程安全的 def use_value_array_task(v, a): v.value = 3.1415926 for i in range(len(a)): a[i] = a[i] * a[i] def process_use_value_array(): v = multiprocessing.Value('d', 0.) # d是指double类型 a = multiprocessing.Array('i', range(5)) # i是指有符号整数 p = multiprocessing.Process(target=use_value_array_task, args=(v, a)) p.start() p.join() print v.value print a[:] # 8.服务进程,Manager能够控制一个持有Python对象的服务进程,能够容许其它进程经过代理来操纵这些对象。 # Manager支持的对象类型包括:list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Queue, Value, Array # 比直接用Value和Array更加灵活,支持的类型更多,但速度上会有必定的代价 def use_manager_task(d, l): d['pi'] = 3.1415926 for i in range(len(l)): l[i] = l[i] * l[i] def process_use_manager(): m = multiprocessing.Manager() d = m.dict() l = m.list(range(5)) p = multiprocessing.Process(target=use_manager_task, args=(d, l)) p.start() p.join() print d print l # 9.使用Pool工做进程池 def pool_task(x): return x * x def process_pool(): pool = multiprocessing.Pool(processes=3) # 三个工做进程 print pool.map(pool_task, range(10)) for i in pool.imap_unordered(pool_task, range(10)): # 乱序 print i, print res = pool.apply_async(pool_task, (3,)) # 只运行一个进程 print res.get(timeout=1) res = pool.apply_async(os.getpid, ()) # 只运行一个进程,异步运行os.getpid() print res.get(timeout=1) # 进程的ID results = [pool.apply_async(os.getpid, ()) for _ in range(3)] print [res.get(timeout=1) for res in results] res = pool.apply_async(time.sleep, (10,)) # 一个进程睡眠10秒 try: print res.get(timeout=1) except multiprocessing.TimeoutError: print u'TimeoutError异常!' if __name__ == '__main__': print u'1.单进程:\n' process_target_1() print '*' * 50 print u'2.多进程:\n' process_multi_tasks() print '*' * 50 print u'3.经过继承自定义进程类:\n' customized_process() print '*' * 50 print u'4.使用Lock进行进程间同步,避免资源访问的冲突:\n' process_use_lock_task() print '*' * 50 print u'5.使用Queue实现多进程之间数据传递,Queue是多进程安全的队列:\n' process_use_queue() print '*' * 50 print u'6.使用Pipe能够创建一对链接对象,俩链接对象是双工工做的:\n' process_use_pipe() print '*' * 50 print u'7.使用Value或Array共享资源,共享的对象是进程安全的:\n' process_use_value_array() print '*' * 50 print u'8.服务进程,Manager:\n' process_use_manager() print '*' * 50 print u'9.使用Pool工做进程池:\n' process_pool() ''' 输出结果: 1.单进程: 进程ID:9200 进程名:Process-1 进程活着吗?True 时间点:Thu Jun 27 13:49:30 2019 时间点:Thu Jun 27 13:49:33 2019 时间点:Thu Jun 27 13:49:36 2019 ************************************************** 2.多进程: CPU数为:16 子进程名:Process-2,ID:10684 子进程名:Process-3,ID:7680 子进程名:Process-4,ID:5884 任务1开始 任务3开始 任务2开始 任务3结束 任务2结束 任务1结束 多进程任务结束 ************************************************** 3.经过继承自定义进程类: 时间点:Thu Jun 27 13:49:42 2019 时间点:Thu Jun 27 13:49:45 2019 时间点:Thu Jun 27 13:49:48 2019 ************************************************** 4.使用Lock进行进程间同步,避免资源访问的冲突: 数字:0 数字:1 数字:2 数字:3 数字:4 数字:5 数字:6 数字:7 数字:8 数字:9 ************************************************** 5.使用Queue实现多进程之间数据传递,Queue是多进程安全的队列: [1, None, 'Good'] ************************************************** 6.使用Pipe能够创建一对链接对象,俩链接对象是双工工做的: ['circle', {'cx': 5}, {'cy': 3}, {'radius': 5}] ['circle', {'cx': 5}, {'cy': 3}, {'radius': 5}] ************************************************** 7.使用Value或Array共享资源,共享的对象是进程安全的: 3.1415926 [0, 1, 4, 9, 16] ************************************************** 8.服务进程,Manager: {'pi': 3.1415926} [0, 1, 4, 9, 16] ************************************************** 9.使用Pool工做进程池: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 0 1 4 9 16 25 36 49 64 81 9 10916 [8416, 10916, 8416] TimeoutError异常! '''
源码可于github下载:https://github.com/gkimeeq/PythonLearning。html