丹哥 發表於 2019-11-14 18:18:00

Python进程池multiprocessing.Pool的用法

<p><strong>一、multiprocessing模块</strong></p>
<p><code>multiprocessing</code>模块提供了一个<code>Process</code>类来代表一个进程对象,multiprocessing模块像线程一样管理进程,这个是multiprocessing的核心,它与threading很相似,对多核CPU的利用率会比threading好的多</p>
<p>看一下Process类的构造方法:</p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px"><span style="color: rgba(128, 0, 128, 1)">__init__</span>(self, group=None, target=None, name=None, args=(), kwargs={})</span></pre>
</div>
<p><strong>参数说明:</strong>&nbsp;<br><strong>group</strong>:进程所属组(基本不用)&nbsp;<br><strong>target</strong>:表示调用对象<br><strong>args</strong>:表示调用对象的位置参数元组<br><strong>name</strong>:别名&nbsp;<br><strong>kwargs</strong>:表示调用对象的字典</p>
<p>示例:</p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px"><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> multiprocessing


</span><span style="color: rgba(0, 0, 255, 1)">def</span> do(n):             <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 参数n由args=(1,)传入</span>
    name = multiprocessing.current_process().name      <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 获取当前进程的名字</span>
    <span style="color: rgba(0, 0, 255, 1)">print</span>(name, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">starting</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">worker </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, n)
    </span><span style="color: rgba(0, 0, 255, 1)">return</span>


<span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(128, 0, 128, 1)">__name__</span> == <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">__main__</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">:
    numList </span>=<span style="color: rgba(0, 0, 0, 1)"> []
    </span><span style="color: rgba(0, 0, 255, 1)">for</span> i <span style="color: rgba(0, 0, 255, 1)">in</span> range(5<span style="color: rgba(0, 0, 0, 1)">):
      p </span>= multiprocessing.Process(target=do, args=(i,))      <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> (i,)中加入","表示元祖</span>
<span style="color: rgba(0, 0, 0, 1)">      numList.append(p)
      </span><span style="color: rgba(0, 0, 255, 1)">print</span><span style="color: rgba(0, 0, 0, 1)">(numList)
      p.start()               </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 用start()方法启动进程,执行do()方法</span>
      p.join()                  <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 等待子进程结束以后再继续往下运行,通常用于进程间的同步</span>
      <span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Process end.</span><span style="color: rgba(128, 0, 0, 1)">"</span>)</span></pre>
</div>
<p>运行结果:</p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">[&lt;Process(Process-1, initial)&gt;<span style="color: rgba(0, 0, 0, 1)">]
Process</span>-1<span style="color: rgba(0, 0, 0, 1)"> starting
worker0
Process end.
[</span>&lt;Process(Process-1, stopped)&gt;, &lt;Process(Process-2, initial)&gt;<span style="color: rgba(0, 0, 0, 1)">]
Process</span>-2<span style="color: rgba(0, 0, 0, 1)"> starting
worker</span>1<span style="color: rgba(0, 0, 0, 1)">
Process end.
[</span>&lt;Process(Process-1, stopped)&gt;, &lt;Process(Process-2, stopped)&gt;, &lt;Process(Process-3, initial)&gt;<span style="color: rgba(0, 0, 0, 1)">]
Process</span>-3<span style="color: rgba(0, 0, 0, 1)"> starting
worker</span>2<span style="color: rgba(0, 0, 0, 1)">
Process end.
[</span>&lt;Process(Process-1, stopped)&gt;, &lt;Process(Process-2, stopped)&gt;, &lt;Process(Process-3, stopped)&gt;, &lt;Process(Process-4, initial)&gt;<span style="color: rgba(0, 0, 0, 1)">]
Process</span>-4<span style="color: rgba(0, 0, 0, 1)"> starting
worker</span>3<span style="color: rgba(0, 0, 0, 1)">
Process end.
<strong>[</strong></span><strong>&lt;Process(Process-1, stopped)&gt;, &lt;Process(Process-2, stopped)&gt;, &lt;Process(Process-3, stopped)&gt;, &lt;Process(Process-4, stopped)&gt;, &lt;Process(Process-5, initial)&gt;</strong><span style="color: rgba(0, 0, 0, 1)"><strong>]</strong>
Process</span>-5<span style="color: rgba(0, 0, 0, 1)"> starting
worker</span>4<span style="color: rgba(0, 0, 0, 1)">
Process end.</span></span></pre>
</div>
<p>通过打印numList可以看出当前进程结束后,再开始下一个进程</p>
<p><strong>注意:</strong>&nbsp;<br>在Windows上要想使用进程模块,就必须把有关进程的代码写在当前.py文件的<strong>if __name__ == ‘__main__’ :语句的下面</strong>,才能正常使用Windows下的进程模块。Unix/Linux下则不需要</p>
<p><span style="font-size: 16px"><strong>二、Pool类</strong></span></p>
<p>&nbsp;Pool类可以提供指定数量的进程供用户调用,当有新的请求提交到Pool中时,如果池还没有满,就会创建一个新的进程来执行请求。如果池满,请求就会告知先等待,直到池中有进程结束,才会创建新的进程来执行这些请求<br>下面介绍一下multiprocessing 模块下的Pool类下的几个方法:</p>
<p><strong>1.apply()</strong></p>
<p>函数原型:apply(func[, args=()[, kwds={}]])</p>
<p>该函数用于传递不定参数,同python中的apply函数一致,主进程会被阻塞直到函数执行结束(不建议使用,并且3.x以后不再出现)</p>
<p><strong>2.apply_async</strong></p>
<p>函数原型:apply_async(func[, args=()[, kwds=<span class="hljs-list">{}[, callback=<span class="hljs-keyword">None]]])</span></span></p>
<p>与apply用法一致,但它是非阻塞的且支持结果返回后进行回调</p>
<p><strong>3.map()</strong></p>
<p>函数原型:<span class="hljs-built_in">map(func, iterable<span class="hljs-preprocessor">[, chunksize<span class="hljs-subst">=<span class="hljs-literal">None<span class="hljs-preprocessor">]<span class="hljs-markup">)</span></span></span></span></span></span></p>
<p>Pool类中的map方法,与内置的map函数用法行为基本一致,它会使进程阻塞直到结果返回<br>注意:虽然第二个参数是一个迭代器,但在实际使用中,必须在整个队列都就绪后,程序才会运行子进程</p>
<p><strong>4.map_async()</strong></p>
<p>函数原型:map_async(func, iterable[, chunksize[, callback]])<br>与map用法一致,但是它是非阻塞的</p>
<p><strong>5.close()</strong></p>
<p>关闭进程池(pool),使其不再接受新的任务</p>
<p><strong>6.terminal()</strong></p>
<p>结束工作进程,不再处理未处理的任务</p>
<p><strong>7.join()</strong></p>
<p>主进程阻塞等待子进程的退出, join方法要在close或terminate之后使用</p>
<p><strong>示例1--使用map()函数</strong></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px"><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> time
</span><span style="color: rgba(0, 0, 255, 1)">from</span> multiprocessing <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> Pool


</span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> run(fn):
    </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> fn: 函数参数是数据列表的一个元素</span>
    time.sleep(1<span style="color: rgba(0, 0, 0, 1)">)
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(fn *<span style="color: rgba(0, 0, 0, 1)"> fn)


</span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(128, 0, 128, 1)">__name__</span> == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">__main__</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">:
    testFL </span>=
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">shunxu:</span><span style="color: rgba(128, 0, 0, 1)">'</span>)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 顺序执行(也就是串行执行,单进程)</span>
    s =<span style="color: rgba(0, 0, 0, 1)"> time.time()
    </span><span style="color: rgba(0, 0, 255, 1)">for</span> fn <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> testFL:
      run(fn)
    t1 </span>=<span style="color: rgba(0, 0, 0, 1)"> time.time()
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">顺序执行时间:</span><span style="color: rgba(128, 0, 0, 1)">"</span>, int(t1 -<span style="color: rgba(0, 0, 0, 1)"> s))

    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">concurrent:</span><span style="color: rgba(128, 0, 0, 1)">'</span>)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 创建多个进程,并行执行</span>
    <strong>pool = Pool(3)</strong><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 创建拥有3个进程数量的进程池</span>
    <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> testFL:要处理的数据列表,run:处理testFL列表中数据的函数</span>
<span style="color: rgba(0, 0, 0, 1)"><strong>    pool.map(run, testFL)</strong>
    <strong>pool.close()</strong></span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 关闭进程池,不再接受新的进程</span>
    <strong>pool.join()</strong><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 主进程阻塞等待子进程的退出</span>
    t2 =<span style="color: rgba(0, 0, 0, 1)"> time.time()
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">并行执行时间:</span><span style="color: rgba(128, 0, 0, 1)">"</span>, int(t2 - t1))</span></pre>
</div>
<p>运行结果:</p>
<p><img src="https://img2018.cnblogs.com/blog/907091/201911/907091-20191114143334949-408022299.png" alt=""></p>
<p>1、map函数中testFL为可迭代对象--列表</p>
<p>2、当创建3个进程时,会一次打印出3个结果“1,4,9”,当当创建2个进程时,会一次打印出2个结果“1,4”,以此类推,当创建多余6个进程时,会一次打印出所有结果</p>
<p>3、如果使用Pool(),不传入参数,可以创建一个动态控制大小的进程池</p>
<p><img src="https://img2018.cnblogs.com/blog/907091/201911/907091-20191114143046705-760231503.png" alt=""></p>
<p><img src="https://img2018.cnblogs.com/blog/907091/201911/907091-20191114143124064-1019380436.png" alt=""></p>
<p>从结果可以看出,并发执行的时间明显比顺序执行要快很多,但是进程是要耗资源的,所以平时工作中,进程数也不能开太大。&nbsp;对Pool对象调用join()方法会等待所有子进程执行完毕,调用join()之前必须先调用close(),让其不再接受新的Process了</p>
<p><strong>示例2--使用map()_async函数</strong></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px"><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">concurrent:</span><span style="color: rgba(128, 0, 0, 1)">'</span>)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 创建多个进程,并行执行</span>
    pool = Pool(3)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 创建拥有3个进程数量的进程池</span>
    <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> testFL:要处理的数据列表,run:处理testFL列表中数据的函数</span>
<strong><span style="color: rgba(0, 0, 0, 1)">    pool.map_async(run, testFL)</span></strong>
    pool.close()<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 关闭进程池,不再接受新的进程</span>
    pool.join()<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 主进程阻塞等待子进程的退出</span>
    t2 =<span style="color: rgba(0, 0, 0, 1)"> time.time()
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">并行执行时间:</span><span style="color: rgba(128, 0, 0, 1)">"</span>, int(t2 - t1))</span></pre>
</div>
<p>运行结果:</p>
<p><img src="https://img2018.cnblogs.com/blog/907091/201911/907091-20191114152602502-446063204.png" alt=""></p>
<p>从结果可以看出,map_async()和map()用时相同。<strong>目前还没有看出两者的区别,后面知道后再完善</strong></p>
<p><strong>示例3--使用apply()函数</strong></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">    <span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">concurrent:</span><span style="color: rgba(128, 0, 0, 1)">'</span>)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 创建多个进程,并行执行</span>
    pool = Pool(3)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 创建拥有3个进程数量的进程池</span>
    <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> testFL:要处理的数据列表,run:处理testFL列表中数据的函数</span>
    <span style="color: rgba(0, 0, 255, 1)">for</span> fn <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> testFL:
       <strong> pool.apply(run, (fn,))</strong>
    pool.close()</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 关闭进程池,不再接受新的进程</span>
    pool.join()<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 主进程阻塞等待子进程的退出</span>
    t2 =<span style="color: rgba(0, 0, 0, 1)"> time.time()
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">并行执行时间:</span><span style="color: rgba(128, 0, 0, 1)">"</span>, int(t2 - t1))</span></pre>
</div>
<p>运行结果:</p>
<p><strong><img src="https://img2018.cnblogs.com/blog/907091/201911/907091-20191114150628889-127262762.png" alt=""></strong></p>
<p>可见,使用apply()方法,并行执行和顺序执行用时相同,经过试验,进程数目增大也不会减少并行执行的时间</p>
<p>原因:以阻塞的形式产生进程任务,生成1个任务进程并等它执行完出池,第2个进程才会进池,主进程一直阻塞等待,每次只执行1个进程任务</p>
<p><strong>示例4--使用apply_async()函数</strong></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px"><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">concurrent:</span><span style="color: rgba(128, 0, 0, 1)">'</span>)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 创建多个进程,并行执行</span>
    pool = Pool(3)<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 创建拥有3个进程数量的进程池</span>
    <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> testFL:要处理的数据列表,run:处理testFL列表中数据的函数</span>
    <span style="color: rgba(0, 0, 255, 1)">for</span> fn <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> testFL:<strong>
      pool.apply_async(run, (fn,))</strong>
    pool.close()</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 关闭进程池,不再接受新的进程</span>
    pool.join()<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 主进程阻塞等待子进程的退出</span>
    t2 =<span style="color: rgba(0, 0, 0, 1)"> time.time()
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">并行执行时间:</span><span style="color: rgba(128, 0, 0, 1)">"</span>, int(t2 - t1))</span></pre>
</div>
<p>运行结果:</p>
<p><img src="https://img2018.cnblogs.com/blog/907091/201911/907091-20191114151120138-1982608012.png" alt=""></p>
<p>可见,使用apply_async()方法,并行执行时间与使用map()、map_async()方法相同</p>
<p><strong>注意:</strong></p>
<p>map_async()和map()方法,第2个参数可以是列表也可以是元祖,如下图:</p>
<p><strong><img src="https://img2018.cnblogs.com/blog/907091/201911/907091-20191114152438864-1135051135.png" alt=""></strong></p>
<p>而使用apply()和apply_async()方法时,第2个参数只能传入元祖,传入列表进程不会被执行,如下图:</p>
<p><img src="https://img2018.cnblogs.com/blog/907091/201911/907091-20191114154639828-1370795471.png" alt=""></p>
<p><span style="font-size: 16px"><strong>三、apply_async()方法callback参数的用法</strong></span></p>
<p><span style="font-size: 14px">示例:</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px"><span style="color: rgba(0, 0, 255, 1)">from</span> multiprocessing <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> Pool
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> time


</span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> fun_01(i):
    time.sleep(</span>2<span style="color: rgba(0, 0, 0, 1)">)
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">start_time:</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, time.ctime())
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> i + 100


<span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> fun_02(arg):
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">end_time:</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, arg, time.ctime())


</span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(128, 0, 128, 1)">__name__</span> == <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">__main__</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">:
    pool </span>= Pool(3<span style="color: rgba(0, 0, 0, 1)">)
    </span><span style="color: rgba(0, 0, 255, 1)">for</span> i <span style="color: rgba(0, 0, 255, 1)">in</span> range(4<span style="color: rgba(0, 0, 0, 1)">):
      pool.apply_async(func</span>=fun_01, args=(i,), callback=fun_02)<strong><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> fun_02的入参为fun_01的返回值</span></strong>
      <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> pool.apply_async(func=fun_01, args=(i,))</span>
<span style="color: rgba(0, 0, 0, 1)">    pool.close()
    pool.join()
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">done</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</span></pre>
</div>
<p>运行结果:</p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">start_time: Thu Nov 14 16:31:41 2019<span style="color: rgba(0, 0, 0, 1)">
end_time: </span>100 Thu Nov 14 16:31:41 2019<span style="color: rgba(0, 0, 0, 1)">
start_time: Thu Nov </span>14 16:31:41 2019<span style="color: rgba(0, 0, 0, 1)">
end_time: </span>101 Thu Nov 14 16:31:41 2019<span style="color: rgba(0, 0, 0, 1)">
start_time: Thu Nov </span>14 16:31:41 2019<span style="color: rgba(0, 0, 0, 1)">
end_time: </span>102 Thu Nov 14 16:31:41 2019<span style="color: rgba(0, 0, 0, 1)">
start_time: Thu Nov </span>14 16:31:43 2019<span style="color: rgba(0, 0, 0, 1)">
end_time: </span>103 Thu Nov 14 16:31:43 2019<span style="color: rgba(0, 0, 0, 1)">
done</span></span></pre>
</div>
<p>map_async()方法callback参数的用法与apply_async()相同</p>
<p><span style="font-size: 16px"><strong>四、使用进程池并关注结果</strong></span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px"><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> multiprocessing
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> time


</span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> func(msg):
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">hello :</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, msg, time.ctime())
    time.sleep(</span>2<span style="color: rgba(0, 0, 0, 1)">)
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">end</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, time.ctime())
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">done</span><span style="color: rgba(128, 0, 0, 1)">'</span> +<span style="color: rgba(0, 0, 0, 1)"> msg


</span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(128, 0, 128, 1)">__name__</span> == <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">__main__</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">:
    pool </span>= multiprocessing.Pool(2<span style="color: rgba(0, 0, 0, 1)">)
    result </span>=<span style="color: rgba(0, 0, 0, 1)"> []
    </span><span style="color: rgba(0, 0, 255, 1)">for</span> i <span style="color: rgba(0, 0, 255, 1)">in</span> range(3<span style="color: rgba(0, 0, 0, 1)">):
      msg </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">hello %s</span><span style="color: rgba(128, 0, 0, 1)">'</span> %<span style="color: rgba(0, 0, 0, 1)"> i
      result.append(pool.apply_async(func</span>=func, args=<span style="color: rgba(0, 0, 0, 1)">(msg,)))

    pool.close()
    pool.join()

    </span><span style="color: rgba(0, 0, 255, 1)">for</span> res <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> result:
      </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">***:</span><span style="color: rgba(128, 0, 0, 1)">'</span>, res.get())             <strong><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> get()函数得出每个返回结果的值</span></strong>

    <span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">All end--</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</span></pre>
</div>
<p>运行结果:</p>
<p><img src="https://img2018.cnblogs.com/blog/907091/201911/907091-20191114171038817-1324674399.png" alt=""></p>
<p><span style="font-size: 16px"><strong>五、多进程执行多个函数</strong></span></p>
<p>使用apply_async()或者apply()方法,可以实现多进程执行多个方法</p>
<p><span style="font-size: 14px">示例:</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px"><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> multiprocessing
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> time
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> os


</span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> Lee():
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">\nRun task Lee--%s******ppid:%s</span><span style="color: rgba(128, 0, 0, 1)">'</span> % (os.getpid(), os.getppid()), <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">~~~~</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, time.ctime())
    start </span>=<span style="color: rgba(0, 0, 0, 1)"> time.time()
    time.sleep(</span>5<span style="color: rgba(0, 0, 0, 1)">)
    end </span>=<span style="color: rgba(0, 0, 0, 1)"> time.time()
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Task Lee,runs %0.2f seconds.</span><span style="color: rgba(128, 0, 0, 1)">'</span> % (end - start), <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">~~~~</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, time.ctime())


</span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> Marlon():
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">\nRun task Marlon-%s******ppid:%s</span><span style="color: rgba(128, 0, 0, 1)">"</span> % (os.getpid(), os.getppid()), <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">~~~~</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, time.ctime())
    start </span>=<span style="color: rgba(0, 0, 0, 1)"> time.time()
    time.sleep(</span>10<span style="color: rgba(0, 0, 0, 1)">)
    end </span>=<span style="color: rgba(0, 0, 0, 1)"> time.time()
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Task Marlon runs %0.2f seconds.</span><span style="color: rgba(128, 0, 0, 1)">'</span> % (end - start), <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">~~~~</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, time.ctime())


</span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> Allen():
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">\nRun task Allen-%s******ppid:%s</span><span style="color: rgba(128, 0, 0, 1)">"</span> % (os.getpid(), os.getppid()), <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">~~~~</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, time.ctime())
    start </span>=<span style="color: rgba(0, 0, 0, 1)"> time.time()
    time.sleep(</span>15<span style="color: rgba(0, 0, 0, 1)">)
    end </span>=<span style="color: rgba(0, 0, 0, 1)"> time.time()
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Task Allen runs %0.2f seconds.</span><span style="color: rgba(128, 0, 0, 1)">'</span> % (end - start), <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">~~~~</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, time.ctime())


</span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> Frank():
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">\nRun task Frank-%s******ppid:%s</span><span style="color: rgba(128, 0, 0, 1)">"</span> % (os.getpid(), os.getppid()), <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">~~~~</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, time.ctime())
    start </span>=<span style="color: rgba(0, 0, 0, 1)"> time.time()
    time.sleep(</span>20<span style="color: rgba(0, 0, 0, 1)">)
    end </span>=<span style="color: rgba(0, 0, 0, 1)"> time.time()
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Task Frank runs %0.2f seconds.</span><span style="color: rgba(128, 0, 0, 1)">'</span> % (end - start), <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">~~~~</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, time.ctime())


</span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(128, 0, 128, 1)">__name__</span> == <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">__main__</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">:
    func_list </span>=<span style="color: rgba(0, 0, 0, 1)">
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">parent process id %s</span><span style="color: rgba(128, 0, 0, 1)">'</span> %<span style="color: rgba(0, 0, 0, 1)"> os.getpid())

    pool </span>= multiprocessing.Pool(4<span style="color: rgba(0, 0, 0, 1)">)
    </span><span style="color: rgba(0, 0, 255, 1)">for</span> func <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> func_list:
      pool.apply_async(func)

    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Waiting for all subprocesses done...</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
    pool.close()
    pool.join()
    </span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">All subprocesses done.</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</span></pre>
</div>
<p>运行结果:</p>
<div class="cnblogs_code">
<pre><span style="font-size: 14px">parent process id 84172<span style="color: rgba(0, 0, 0, 1)">
Waiting </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> all subprocesses done...

Run task Lee</span>--84868******ppid:84172 ~~~~ Thu Nov 14 17:44:14 2019<span style="color: rgba(0, 0, 0, 1)">

Run task Marlon</span>-84252******ppid:84172 ~~~~ Thu Nov 14 17:44:14 2019<span style="color: rgba(0, 0, 0, 1)">

Run task Allen</span>-85344******ppid:84172 ~~~~ Thu Nov 14 17:44:14 2019<span style="color: rgba(0, 0, 0, 1)">

Run task Frank</span>-85116******ppid:84172 ~~~~ Thu Nov 14 17:44:14 2019<span style="color: rgba(0, 0, 0, 1)">
Task Lee,runs </span>5.00 seconds. ~~~~ Thu Nov 14 17:44:19 2019<span style="color: rgba(0, 0, 0, 1)">
Task Marlon runs </span>10.00 seconds. ~~~~ Thu Nov 14 17:44:24 2019<span style="color: rgba(0, 0, 0, 1)">
Task Allen runs </span>15.00 seconds. ~~~~ Thu Nov 14 17:44:29 2019<span style="color: rgba(0, 0, 0, 1)">
Task Frank runs </span>20.00 seconds. ~~~~ Thu Nov 14 17:44:34 2019<span style="color: rgba(0, 0, 0, 1)">
All subprocesses done.</span></span></pre>
</div>
<p><span style="font-size: 16px"><strong>六、其他</strong></span></p>
<p><span style="font-size: 14px">1、获取当前计算机的CPU数量</span></p>
<p><img src="https://img2018.cnblogs.com/blog/907091/201911/907091-20191114181426314-737071189.png" alt=""></p>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/ailiailan/p/11850710.html
頁: [1]
查看完整版本: Python进程池multiprocessing.Pool的用法