ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Python multiprocessing多进程原理与应用示例

Python multiprocessing多进程原理与应用示例 多进程原理与应用示例更新时间为二零一九年二月二十八日十四点三十分十五秒, 作者是牧野。这篇文章主要介绍了多进程原理与应用, 它结合了具体的实例形式, 对基于包的多进程概念进行了详细的分析, 深入讲解了其核心原理以及相关的实际操作技巧, 有需要的用户可以参考这些内容。本文实例主要是讲述多进程原理与应用的事情, 现在分享给大家来供大家参考, 具体内容如下:包里面的多进程管理包, 可以利用那个对象来创建进程, 这个对象上面, 是有这些方法的, 比如说启动方法, 还有join方法, run方法, 以及启动方法。该模块的核心功能, 就是把管理进程变得和管理线程那样轻松顺手, 因为每一个进程都拥有自己独立的GIL, 所以就不会出现进程相互争抢GIL的情况, 这样一来, 在多核CPU运行环境下, 能够把执行运行的效率给大幅度地提升上去。这是使用这个功能的例子。import multiprocessingimport timeimport cv2def daemon1(image):name multiprocessing.current_process().namefor i in range(50):image cv2.GaussianBlur(image, (3, 3), 1)time.sleep(0.1)print daemon1 done!cv2.imshow(daemon1, image)def daemon2(image):name multiprocessing.current_process().namefor i in range(50):image cv2.GaussianBlur(image, (3, 3), 1)time.sleep(0.5)print daemon2 done!cv2.imshow(daemon2, image)if __name__ __main__:t1 time.time()number_kernel multiprocessing.cpu_count()print We have {0} kernels.format(number_kernel)p1 multiprocessing.Process(namedaemon1,targetdaemon1,args (cv2.imread(./p1.jpg),))p1.daemon Falsep2 multiprocessing.Process(namedaemon2,targetdaemon2, args(cv2.imread(./p2.jpg),))p2.daemon Falsep1.start()p2.start()print p1 is {0}.format(p1.is_alive())p1.terminate()p1.join()print p1 is {0}.format(p1.is_alive())print p2 is {0}.format(p2.is_alive())p2.join()t2 time.time()print !!!!!!!!!!!!!!!!!!!!OK!!!!!!!!!!!!!!!!!!!!!print total time is {0}.format(t2-t1)print p1.exitcode {0}.format(p1.exitcode)print p2.exitcode {0}.format(p2.exitcode)“中”这里指的是一个类别, 它的作用是用来创建进程, 同时还包含了定义进程相关方法的功能, 该类所对应的构造函数形式如下:def __init__(self, groupNone, targetNone, nameNone, args(), kwargs{})这个地方的参数指的是啥意思呢?程序解读在中使用pool如果需要进行操作的是多个子进程, 那么采用进程池的方式进行统一管控, 会对每个子进程实施自动化管理, 这样的做法显然是更加便利且高效的。from multiprocessing import Poolimport os, timedef long_time_task(name):print Run task {0} ({1}).format(name,os.getpid())start time.time()time.sleep(3)end time.time()print Task {0} runs {1:.2f} seconds..format(name,end - start)if __name____main__:print Parent process ({0}).format(os.getpid)p Pool()for i in range(12):p.apply_async(long_time_task, args(i,))print Waiting for all subprocesses done...p.close()p.join()print All subprocesses done.跟通过类的实例化方法来创建进程的方式不一样, Pool是借由func,args(args)这种办法来生成进程的。在每一个进程池里面, 能够并行处理的任务数量等于咱们这台机器上面所有CPU核心的总数目。要是弄出来的子进程的数量超过了这个上限, 那么在同一时间里, 就只允许有那一个个数的进程在执行。只有当里面的某一个进程把活儿干完了以后, 才会去启动后续的下一个进程。存在多个子进程, 而这些多个子进程之间需要互相通信。在多个子进程进行通信的时候, 是需要使用到.Queue的, .Queue的特点在于它是一个消息队列。比方说存在如下需求, 也就是有一个实例表现为一个子进程向队列里边写入数据, 而另一个进程从该队列里面获取数据这样的情况。from multiprocessing import Process, Queueimport os, time, randomdef write(q):for value in [A, B, C]:print Put {0} to queue....format(value)q.put(value)time.sleep(random.random())def read(q):while True:if not q.empty():value q.get(True)print Get {0} from queue..format(value)time.sleep(random.random())else:breakif __name____main__:q multiprocessing.Queue()pw Process(targetwrite, args(q,))pr Process(targetread, args(q,))pw.start()pw.join()pr.start()pr.join()Queue的使用方法, 是这样子的。如果在进程池Pool中尝试使用Queue, 是会出错的, 所以, 应该改用那个带有点号的.Queue才行。from multiprocessing import Process, Queueimport os, time, randomdef write(q):for value in [A, B, C]:print Put {0} to queue....format(value)q.put(value)time.sleep(random.random())def read(q):while True:if not q.empty():value q.get(True)print Get {0} from queue..format(value)time.sleep(random.random())else:breakif __name____main__:manager multiprocessing.Manager()q manager.Queue()p Pool()pw p.apply_async(write, args(q,))time.sleep(2)pr p.apply_async(read, args(q,))p.close()p.join()if not q.empty():print q is not empty...else:print q is empty...print OKif not q.empty():print q is not empty...else:print q is empty...print done...父进程与子进程共享内存定义普通的变量不能实现在父进程和子进程之间共享import multiprocessingfrom multiprocessing import Pooldef changevalue(n, a):n 3.14a[0] 5if __name__ __main__:num 0arr range(10)p Pool()p1 p.apply_async(changevalue, args(num, arr))p.close()p.join()print numprint arr[:]导致最终输出的 num 的数值, 依然是由父进程那边定义的 0, 同时 arr 的第一个元素的值, 也依旧是 0。使用那个, 来把共享的这个对象进行创建的。import multiprocessingdef changevalue(n, a):n.value 3.14a[0] 5if __name__ __main__:num multiprocessing.Value(d, 0.0)arr multiprocessing.Array(i, range(10))p multiprocessing.Process(targetchangevalue, args(num, arr))p.start()p.join()print num.valueprint arr[:]最终输出的结果是num这个变量的值被修改成了3.14, 而这个修改的动作发生在子进程内部。与此同时, arr数组里的第一个元素值也被更改为了数字5。共享内存是在那个叫做pool的地方进行使用的, 具体的情况说明如下面所说的一样。import multiprocessingfrom multiprocessing import Pooldef changevalue(n, a):n.value 3.14a[0] 5if __name__ __main__:num multiprocessing.Value(d, 0.0)arr multiprocessing.Array(i, range(10))p Pool()p1 p.apply_async(changevalue, args(num, arr))p.close()p.join()print num.valueprint arr[:]更多关于相关内容感兴趣的读者可查看本站专题《进程与线程操作技巧总结》、《数据结构与算法教程》、《函数使用技巧总结》、《字符串操作技巧汇总》、《入门与进阶经典教程》、《MySQL数据库程序设计入门教程》及《常见数据库操作技巧汇总》本人希望在此文本中所阐述的相关内容, 能够对各位朋友在程序设计的方面, 带来一定的、并且是有益的参考与帮助。
返回列表