玉饰销售 發表於 2020-9-17 18:19:00

python 进程(process)阻塞

<p>本文链接:https://www.cnblogs.com/tujia/p/13686684.html</p>
<p>&nbsp;</p>
<p>背景:来观察测试一下python&nbsp;进程(process)的阻塞、普通进程和守护进程又有什么区别、进程池又是什么、进程池怎么异步提交任务等等</p>
<p>&nbsp;</p>
<p><strong>一、公共代码</strong></p>
<p>首先先贴上一些公共代码,<span style="color: rgba(255, 0, 0, 1)">下面的例子都基于这份公共代码运行(注:替换xxx的内容)</span></p>
<div class="cnblogs_code">
<pre><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)"> multiprocessing


</span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> worker(name):
    </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)">%s: %s start...</span><span style="color: rgba(128, 0, 0, 1)">'</span> % (time.strftime(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">%X</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">), name))
    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)">%s: %s done.</span><span style="color: rgba(128, 0, 0, 1)">'</span> % (time.strftime(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">%X</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">), name))


</span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> xxx():
    </span><span style="color: rgba(0, 0, 255, 1)">pass</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)">:
    xxx()</span></pre>
</div>
<p>&nbsp;</p>
<p><strong>二、单进程阻塞</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> 单进程阻塞():
    t </span>= multiprocessing.Process(target=worker, args=(<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)">,))
    t.start()
    </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 阻塞</span>
<span style="color: rgba(0, 0, 0, 1)">    t.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)">Finished</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p>运行结果:</p>
<p><img src="https://img2020.cnblogs.com/blog/550797/202009/550797-20200917161744398-414055938.png"></p>
<p><span style="color: rgba(255, 0, 0, 1)">解释:阻塞进程的情况下,程序会先等待进程任务执行完,再往下执行其他代码&nbsp;&nbsp;</span></p>
<p>&nbsp;</p>
<p><strong>三、单进程不阻塞</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> 单进程不阻塞():
    t </span>= multiprocessing.Process(target=worker, args=(<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)">,))
    t.start()
    </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)">Finished</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p>运行结果:</p>
<p><img src="https://img2020.cnblogs.com/blog/550797/202009/550797-20200917161951804-345859249.png"></p>
<p><span style="color: rgba(255, 0, 0, 1)">解释:不阻塞进程的情况下,程序会直接往下走,进程任务是后完成的(因为我在进程任务里加了 sleep),类似于异步;同时,我们还可以发现,程序执行完最后一行代码之后,如果进程任务还没完成,程序是不会马上死掉的,还是会等进程任务执行完才会结束程序。</span></p>
<p>&nbsp;</p>
<p><strong>四、多进程的错误阻塞</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> 多进程的错误阻塞():
    t1 </span>= multiprocessing.Process(target=worker, args=(<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)">,))
    t1.start()
    t1.join()
    t2 </span>= multiprocessing.Process(target=worker, args=(<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)">,))
    t2.start()
    t2.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)">Finished</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p>运行结果:</p>
<p><img src="https://img2020.cnblogs.com/blog/550797/202009/550797-20200917164755312-2087866378.png"></p>
<p><span style="color: rgba(255, 0, 0, 1)">解释:t1.join&nbsp;直接阻塞了程序,t2还没start,t1.join阻塞程序直到t1的任务已完成。所以会看到&nbsp;张三 done&nbsp;之后,李四&nbsp;才能 start</span></p>
<p>&nbsp;</p>
<p><strong>五、多进程的正确阻塞</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> 多进程的正确阻塞():
    t1 </span>= multiprocessing.Process(target=worker, args=(<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)">,))
    t2 </span>= multiprocessing.Process(target=worker, args=(<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)">,))
    t1.start()
    t2.start()
    t1.join()
    t2.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)">Finished</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p>运行结果:</p>
<p><img src="https://img2020.cnblogs.com/blog/550797/202009/550797-20200917165635443-2130248043.png">&nbsp;&nbsp;<img src="https://img2020.cnblogs.com/blog/550797/202009/550797-20200917165651503-631959172.png"></p>
<p><span style="color: rgba(255, 0, 0, 1)">解释:需要将所有进程都start之后,才能阻塞(join);进程任务也不是按顺序执行和完成了,哪个先完成,得看哪个进程任务耗时少,也有可能会同时完成(并发)&nbsp;</span></p>
<p>按下面代码,修改一下worker函数,给李四加一下速,再执行一次看看:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> worker(name):
    </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)">%s: %s start...</span><span style="color: rgba(128, 0, 0, 1)">'</span> % (time.strftime(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">%X</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">), name))
    time.sleep(</span>2 <span style="color: rgba(0, 0, 255, 1)">if</span> name == <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, 255, 1)">else</span> 1<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)">%s: %s done.</span><span style="color: rgba(128, 0, 0, 1)">'</span> % (time.strftime(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">%X</span><span style="color: rgba(128, 0, 0, 1)">'</span>), name))</pre>
</div>
<p><img src="https://img2020.cnblogs.com/blog/550797/202009/550797-20200917170626002-58287770.png"></p>
<p>注:多执行几次,你会发现,明明是t1.start() 再 t2.start(),为何回显总是&nbsp;李四 start&nbsp;在前。那是因为<span style="color: rgba(255, 0, 0, 1)">阻塞的进程,执行过程中是不会回显的,它需要执行完毕后才会一起回显</span>。因为总是&nbsp;李四 done&nbsp;先,所以回显示就总是&nbsp;李四 start&nbsp;在前</p>
<p>&nbsp;</p>
<p><span style="color: rgba(255, 0, 0, 1)"><strong>温馨提示:测试完记得把 worker&nbsp;函数改回原来的样子,下面例子是以原版的 worker&nbsp;为基础的</strong></span></p>
<p>&nbsp;</p>
<p><strong>六、多进程不阻塞</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> 多进程不阻塞():
    t1 </span>= multiprocessing.Process(target=worker, args=(<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)">,))
    t2 </span>= multiprocessing.Process(target=worker, args=(<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)">,))
    t1.start()
    t2.start()
    </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)">Finished</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p>运行结果:</p>
<p><img src="https://img2020.cnblogs.com/blog/550797/202009/550797-20200917172251794-147086182.png">&nbsp;&nbsp;<img src="https://img2020.cnblogs.com/blog/550797/202009/550797-20200917172324869-1165393624.png"></p>
<p><span style="color: rgba(255, 0, 0, 1)">解释:&nbsp;参考上面单进程不阻塞↑,不阻塞的情况下,也是会等待全部进程任务执行完成才结束程序的。多进程有一定的并发现象</span></p>
<p>&nbsp;</p>
<p><strong>七、守护进程阻塞</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> 守护进程阻塞():
    t1 </span>= multiprocessing.Process(daemon=True, target=worker, args=(<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)">,))
    t2 </span>= multiprocessing.Process(daemon=True, target=worker, args=(<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)">,))
    t1.start()
    t2.start()
    t1.join()
    t2.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)">Finished</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p>运行结果:</p>
<p><img src="https://img2020.cnblogs.com/blog/550797/202009/550797-20200917172450546-2135194168.png"></p>
<p><span style="color: rgba(255, 0, 0, 1)">解释:这里看着上面的普通进程没有什么区别的,具体的区别看下面↓↓↓</span></p>
<p>&nbsp;</p>
<p><strong>八、守护进程不阻塞</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> 守护进程不阻塞():
    t1 </span>= multiprocessing.Process(daemon=True, target=worker, args=(<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)">,))
    t2 </span>= multiprocessing.Process(daemon=True, target=worker, args=(<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)">,))
    t1.start()
    t2.start()
    </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)">Finished</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p>运行结果:</p>
<p><img src="https://img2020.cnblogs.com/blog/550797/202009/550797-20200917172706961-1513077089.png"></p>
<p><span style="color: rgba(255, 0, 0, 1)">解释:进程任务都还没执行,主程序就执行完毕,结束了。这是守护进程(后台进程)的一个特点:不阻塞的情况下,后台进程(守护进程)会在主程序结束的时候自动死掉</span></p>
<p>&nbsp;</p>
<p><strong>九、守护进程不阻塞但主进程比较晚结束</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> 守护进程不阻塞但主进程比较晚结束():
    t1 </span>= multiprocessing.Process(daemon=True, target=worker, args=(<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)">,))
    t2 </span>= multiprocessing.Process(daemon=True, target=worker, args=(<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)">,))
    t1.start()
    t2.start()
    time.sleep(</span>5<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)">Finished</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p>运行结果:</p>
<p><img src="https://img2020.cnblogs.com/blog/550797/202009/550797-20200917172956213-887680419.png"></p>
<p><span style="color: rgba(255, 0, 0, 1)">解释:这里的主进程并没有等子(守护)进程,只是主进程耗时比子进程还要久,子进程先执行完毕了&nbsp;</span></p>
<p>&nbsp;</p>
<p><strong>十、进程池阻塞</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> 进程池阻塞():
    with multiprocessing.Pool(processes</span>=3<span style="color: rgba(0, 0, 0, 1)">) as pp:
      pp.apply(worker, (</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><span style="color: rgba(0, 0, 0, 1)">,))
      pp.apply(worker, (</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><span style="color: rgba(0, 0, 0, 1)">,))
      pp.close()
      pp.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)">Finished</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p>运行结果:</p>
<p><img src="https://img2020.cnblogs.com/blog/550797/202009/550797-20200917173317054-1417660432.png"></p>
<p><span style="color: rgba(255, 0, 0, 1)">解释:运行结果基本和“多进程的正确阻塞”基本一样,但又有一点不同,详情请看下面 “十二” 点~</span></p>
<p>&nbsp;</p>
<p><strong>十一、进程池不阻塞</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> 进程池不阻塞():
    with multiprocessing.Pool(processes</span>=3<span style="color: rgba(0, 0, 0, 1)">) as pp:
      pp.apply(worker, (</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><span style="color: rgba(0, 0, 0, 1)">,))
      pp.apply(worker, (</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><span style="color: rgba(0, 0, 0, 1)">,))
      pp.close()
    </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)">Finished</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p>运行结果:</p>
<p><img src="https://img2020.cnblogs.com/blog/550797/202009/550797-20200917173645409-1507668342.png"></p>
<p>解释:这不阻塞的效果感觉和阻塞的效果并没有什么区别</p>
<p>&nbsp;</p>
<p><strong>十二、进程池的奇怪现象</strong></p>
<p>认真观察一下“<strong>十、进程池阻塞</strong>”和“<strong>十一、进程池不阻塞</strong>”,还有一个现象,不管是阻塞还是不阻塞,就上面的例子而言,李四居然要等张三done之后才能start,它们不应该同时start,同时done的吗??</p>
<p>对比一下上面“<strong>五、多进程的正确阻塞</strong>”的运行结果&nbsp;和 “<strong>十一、<strong>进程池不阻塞</strong></strong>”的结果:</p>
<p><img src="https://img2020.cnblogs.com/blog/550797/202009/550797-20200917174931789-1271162670.png">&nbsp; &nbsp; &nbsp; &nbsp; 与&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<img src="https://img2020.cnblogs.com/blog/550797/202009/550797-20200917175636794-1491785491.png"></p>
<p>解释:普通的多进程 start&nbsp;是一起的(并发,单任务不阻塞),done的话就看任务的实际耗时。<span style="color: rgba(255, 0, 0, 1)">进程池的话,使用apply添加任务的时候,会自动阻塞任务,一个任务完成,再才执行下一个apply的任务。只想阻塞进程池,不要阻塞单任务的话,可以使用 apply_async&nbsp;方法,详情请看下面↓↓↓</span></p>
<p>&nbsp;</p>
<p><strong>十三、进程池异步阻塞</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> 进程池异步阻塞():
    with multiprocessing.Pool(processes</span>=3<span style="color: rgba(0, 0, 0, 1)">) as pp:
      pp.apply_async(worker, (</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><span style="color: rgba(0, 0, 0, 1)">,))
      pp.apply_async(worker, (</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><span style="color: rgba(0, 0, 0, 1)">,))
      pp.close()
      pp.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)">Finished</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p>运行结果:</p>
<p><img src="https://img2020.cnblogs.com/blog/550797/202009/550797-20200917180118813-1192269213.png"></p>
<p><span style="color: rgba(255, 0, 0, 1)">解释,这下就真的和“多进程的正确阻塞”一样的,不会阻塞单任务</span></p>
<p>&nbsp;</p>
<p><strong>十四、进程池异步不阻塞</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> 进程池异步不阻塞():
    with multiprocessing.Pool(processes</span>=3<span style="color: rgba(0, 0, 0, 1)">) as pp:
      pp.apply_async(worker, (</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><span style="color: rgba(0, 0, 0, 1)">,))
      pp.apply_async(worker, (</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><span style="color: rgba(0, 0, 0, 1)">,))
      pp.close()
    </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)">Finished</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p>运行结果:</p>
<p><img src="https://img2020.cnblogs.com/blog/550797/202009/550797-20200917180221086-2068859282.png"></p>
<p><span style="color: rgba(255, 0, 0, 1)">解释:异步不阻塞的话,就会和守护进程一样,主程序不会等待进程任务完成,会直接结束程序</span></p>
<p>&nbsp;</p>
<p><strong>十五、进程池同步并发不阻塞</strong></p>
<p>上面说的apply是同步提交任务,apply_async是异步提交任务。apply是会阻塞的,顺序执行任务。那有没有同步又并发的方法呢?答案是有的,可以用map方法:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> 进程池同步并发不阻塞():
    with multiprocessing.Pool(processes</span>=3<span style="color: rgba(0, 0, 0, 1)">) as pp:
      pp.map(worker, [</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>, <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)">])
      pp.close()
    </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)">Finished</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p>运行结果:</p>
<p><img src="https://img2020.cnblogs.com/blog/550797/202009/550797-20200917181039192-1718417086.png"></p>
<p><span style="color: rgba(255, 0, 0, 1)">解释:提供给map方法一个函数和参数列表,它会迭代参数列表,并发执行函数~</span></p>
<p>&nbsp;</p>
<p>需要注意的是,map和apply一样,是同步且阻塞的,多次调用map方法会和多次调用apply一样,会阻塞,需要等待第一次map任务执行完毕才会执行下面的map</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> 进程池同步并发阻塞():
    with multiprocessing.Pool(processes</span>=3<span style="color: rgba(0, 0, 0, 1)">) as pp:
      pp.map(worker, [</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>, <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)">])
      pp.map(worker, [</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>, <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)">])
      pp.close()
    </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)">Finished</span><span style="color: rgba(128, 0, 0, 1)">'</span>)</pre>
</div>
<p>运行结果:</p>
<p><img src="https://img2020.cnblogs.com/blog/550797/202009/550797-20200917181546726-1563006525.png"></p>
<p>&nbsp;</p>
<p>本文链接:https://www.cnblogs.com/tujia/p/13686684.html</p>
<hr>
<p>完。&nbsp;</p>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/tujia/p/13686684.html
頁: [1]
查看完整版本: python 进程(process)阻塞