python多任务
一、多任务
1.1 概念
多任务就是指:同一时间能执行多个任务。比方我们的电脑能一边QQ聊天,一边写论文,还能听歌。
1.2 多任务的优势:
多任务的最大好处是 充分利用CPU资源,提高程序的执行效率。
1.3 多任务的两种表现形式:
(1)并发:
在一段时间内交替去执行多个任务。
例子:
对于单核CPU处理多任务,操作系统轮流让各个任务交替执行。如下图所示:
(2)并行:
在一段时间内真正的同时一起执行多个任务。
例子:
对于多核cpu处理多任务,操作系统会给cpu的每个内核安排一个执行的任务, 多个内核是真正的一起同时执行多个任务。这里需要注意多核cpu是并行的执行多任务,始终有多个任务一起执行。
二、进程:
在python中,想要实现多任务,可以使用多进程来实现。
2.1 进程的概念:
进程(Process) 是资源分配的最小单位,它是操作系统进行资源分配和调度运行的基本单位,通俗理解: 一个正在运行的程序就是一个进程。例如:正在运行的qq,微信等,他们都是一个进程。
注意:一个正在运行的程序才叫进程,而没有运行的程序,只能叫程序,不能叫进程。
同时,一个程序可以有一个或者多个进程。
2.2 多进程的作用:
上图中是一个非常简单的程序,一旦运行hello.py这个程序,按照代码的执行顺序,
func_ a
函数执行完毕后才能执行func_ b
函数。如果可以让func a
和func _b
同时运行,显然执行hello.py这个程序的效率会大大提升。
那怎么实现呢?接着看:
如下图所示,当运行hello.py这个程序的时候,先创建一个主进程,之后再创建了一个子进程,让主进程执行func_a,让子进程执行func_b,这样就使用多进程实现了多任务。
2.3 多进程完成多任务:
(1)进程的创建步骤:
- 1、导入进程包:
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python"><span style="color:#ff79c6">import</span> multiprocessing
</code></span></span></span></span>
- 2、通过进程类创建进程对象:
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python">进程对象 <span style="color:#6272a4">=</span> multiprocessing<span style="color:#999999">.</span>Process<span style="color:#999999">(</span>target<span style="color:#6272a4">=</span>任务名<span style="color:#999999">)</span>
</code></span></span></span></span>
- 3、启动进程执行任务:
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python">进程对象<span style="color:#999999">.</span>start<span style="color:#999999">(</span><span style="color:#999999">)</span>
</code></span></span></span></span>
(2)多进程例子:
下面程序是单进程,先执行唱歌的函数,再执行跳舞的函数。需要3秒完成。
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python"><span style="color:#ff79c6">import</span> time<span style="color:#6272a4"># 唱歌</span>
<span style="color:#ff79c6">def</span> <span style="color:#8be9fd">sing</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">for</span> i <span style="color:#ff79c6">in</span> <span style="color:#f1fa8c">range</span><span style="color:#999999">(</span><span style="color:#f1fa8c">3</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"唱歌..."</span><span style="color:#999999">)</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">0.5</span><span style="color:#999999">)</span> <span style="color:#6272a4"># 延迟0.5秒</span>
<span style="color:#6272a4"># 跳舞</span>
<span style="color:#ff79c6">def</span> <span style="color:#8be9fd">dance</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">for</span> i <span style="color:#ff79c6">in</span> <span style="color:#f1fa8c">range</span><span style="color:#999999">(</span><span style="color:#f1fa8c">3</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"跳舞..."</span><span style="color:#999999">)</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">0.5</span><span style="color:#999999">)</span>
<span style="color:#ff79c6">if</span> __name__ <span style="color:#6272a4">==</span> <span style="color:#f1fa8c">"__main__"</span><span style="color:#999999">:</span>sing<span style="color:#999999">(</span><span style="color:#999999">)</span>dance<span style="color:#999999">(</span><span style="color:#999999">)</span>
</code></span></span></span></span>
运行结果:
上面的程序怎么使用多进程实现呢?下面的程序实现了多进程实现多任务,我们会发现,只需要1.5秒执行完了,唱歌和跳舞是交替执行的。
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python"><span style="color:#6272a4"># 1.导入进程包</span>
<span style="color:#ff79c6">import</span> time
<span style="color:#ff79c6">import</span> multiprocessing<span style="color:#6272a4"># 唱歌</span>
<span style="color:#ff79c6">def</span> <span style="color:#8be9fd">sing</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">for</span> i <span style="color:#ff79c6">in</span> <span style="color:#f1fa8c">range</span><span style="color:#999999">(</span><span style="color:#f1fa8c">3</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"唱歌..."</span><span style="color:#999999">)</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">0.5</span><span style="color:#999999">)</span> <span style="color:#6272a4"># 延迟0.5秒</span><span style="color:#6272a4"># 跳舞</span>
<span style="color:#ff79c6">def</span> <span style="color:#8be9fd">dance</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">for</span> i <span style="color:#ff79c6">in</span> <span style="color:#f1fa8c">range</span><span style="color:#999999">(</span><span style="color:#f1fa8c">3</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"跳舞..."</span><span style="color:#999999">)</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">0.5</span><span style="color:#999999">)</span><span style="color:#ff79c6">if</span> __name__ <span style="color:#6272a4">==</span> <span style="color:#f1fa8c">"__main__"</span><span style="color:#999999">:</span><span style="color:#6272a4"># 2.使用进程类创建进程对象</span>sing_process <span style="color:#6272a4">=</span> multiprocessing<span style="color:#999999">.</span>Process<span style="color:#999999">(</span>target<span style="color:#6272a4">=</span>sing<span style="color:#999999">)</span>dance_process <span style="color:#6272a4">=</span> multiprocessing<span style="color:#999999">.</span>Process<span style="color:#999999">(</span>target<span style="color:#6272a4">=</span>dance<span style="color:#999999">)</span><span style="color:#6272a4"># 3.使用进程对象启动进程执行指定任务</span>sing_process<span style="color:#999999">.</span>start<span style="color:#999999">(</span><span style="color:#999999">)</span>dance_process<span style="color:#999999">.</span>start<span style="color:#999999">(</span><span style="color:#999999">)</span>
</code></span></span></span></span>
运行结果:
2.4 进程执行带有参数的任务:
(1)参数说明:
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python">进程对象 <span style="color:#6272a4">=</span> multiprocessing<span style="color:#999999">.</span>Process<span style="color:#999999">(</span>target<span style="color:#6272a4">=</span>任务名<span style="color:#999999">,</span> args<span style="color:#999999">,</span> kwargs<span style="color:#999999">)</span>
</code></span></span></span></span>
- 1
(2)例子:
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python"><span style="color:#6272a4"># 1.导入进程包</span>
<span style="color:#ff79c6">import</span> time
<span style="color:#ff79c6">import</span> multiprocessing<span style="color:#6272a4"># 唱歌</span>
<span style="color:#ff79c6">def</span> <span style="color:#8be9fd">sing</span><span style="color:#999999">(</span>num<span style="color:#999999">,</span> name<span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">for</span> i <span style="color:#ff79c6">in</span> <span style="color:#f1fa8c">range</span><span style="color:#999999">(</span>num<span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span>name<span style="color:#999999">)</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"唱歌..."</span><span style="color:#999999">)</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">0.5</span><span style="color:#999999">)</span> <span style="color:#6272a4"># 延迟0.5秒</span><span style="color:#6272a4"># 跳舞</span>
<span style="color:#ff79c6">def</span> <span style="color:#8be9fd">dance</span><span style="color:#999999">(</span>num<span style="color:#999999">,</span> name<span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">for</span> i <span style="color:#ff79c6">in</span> <span style="color:#f1fa8c">range</span><span style="color:#999999">(</span>num<span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span>name<span style="color:#999999">)</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"跳舞..."</span><span style="color:#999999">)</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">0.5</span><span style="color:#999999">)</span><span style="color:#ff79c6">if</span> __name__ <span style="color:#6272a4">==</span> <span style="color:#f1fa8c">"__main__"</span><span style="color:#999999">:</span><span style="color:#6272a4"># 2.使用进程类创建进程对象</span><span style="color:#6272a4"># args:使用元组方式给指定任务传参</span>sing_process <span style="color:#6272a4">=</span> multiprocessing<span style="color:#999999">.</span>Process<span style="color:#999999">(</span>target<span style="color:#6272a4">=</span>sing<span style="color:#999999">,</span> args<span style="color:#6272a4">=</span><span style="color:#999999">(</span><span style="color:#f1fa8c">3</span><span style="color:#999999">,</span> <span style="color:#f1fa8c">"李华"</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#6272a4"># kwargs:使用字典方式给指定任务传参</span>dance_process <span style="color:#6272a4">=</span> multiprocessing<span style="color:#999999">.</span>Process<span style="color:#999999">(</span>target<span style="color:#6272a4">=</span>dance<span style="color:#999999">,</span> kwargs<span style="color:#6272a4">=</span><span style="color:#999999">{</span><span style="color:#f1fa8c">"num"</span><span style="color:#999999">:</span> <span style="color:#f1fa8c">2</span><span style="color:#999999">,</span> <span style="color:#f1fa8c">"name"</span><span style="color:#999999">:</span><span style="color:#f1fa8c">"小明"</span><span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#6272a4"># 3.使用进程对象启动进程执行指定任务</span>sing_process<span style="color:#999999">.</span>start<span style="color:#999999">(</span><span style="color:#999999">)</span>dance_process<span style="color:#999999">.</span>start<span style="color:#999999">(</span><span style="color:#999999">)</span>
</code></span></span></span></span>
2.5 获取进程编号:
(1)作用:
当程序中进程的数量越来越多时,如果没有办法区分主进程和子进程还有不同的子进程,那么就无法进行有效的进程管理,为了方便管理实际上每个进程都是有自己的编号。
(2)获取进程编号的两种方式:
- (1)获取当前进程编号:
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python"><span style="color:#ff79c6">import</span> osos<span style="color:#999999">.</span>getpid<span style="color:#999999">(</span><span style="color:#999999">)</span>
</code></span></span></span></span>
- (2)获取当前父进程编号:
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python"><span style="color:#ff79c6">import</span> osos<span style="color:#999999">.</span>getppid<span style="color:#999999">(</span><span style="color:#999999">)</span>
</code></span></span></span></span>
(3)例子:
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python"><span style="color:#6272a4"># 1.导入进程包</span>
<span style="color:#ff79c6">import</span> os
<span style="color:#ff79c6">import</span> time
<span style="color:#ff79c6">import</span> multiprocessing<span style="color:#6272a4"># 唱歌</span>
<span style="color:#ff79c6">def</span> <span style="color:#8be9fd">sing</span><span style="color:#999999">(</span>num<span style="color:#999999">,</span> name<span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"唱歌进程编号:"</span><span style="color:#999999">,</span> os<span style="color:#999999">.</span>getpid<span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"唱歌进程的父进程:"</span><span style="color:#999999">,</span> os<span style="color:#999999">.</span>getppid<span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#ff79c6">for</span> i <span style="color:#ff79c6">in</span> <span style="color:#f1fa8c">range</span><span style="color:#999999">(</span>num<span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span>name<span style="color:#999999">)</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"唱歌..."</span><span style="color:#999999">)</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">0.5</span><span style="color:#999999">)</span> <span style="color:#6272a4"># 延迟0.5秒</span><span style="color:#6272a4"># 跳舞</span>
<span style="color:#ff79c6">def</span> <span style="color:#8be9fd">dance</span><span style="color:#999999">(</span>num<span style="color:#999999">,</span> name<span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"跳舞进程编号:"</span><span style="color:#999999">,</span> os<span style="color:#999999">.</span>getpid<span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"跳舞进程的父进程:"</span><span style="color:#999999">,</span> os<span style="color:#999999">.</span>getppid<span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#ff79c6">for</span> i <span style="color:#ff79c6">in</span> <span style="color:#f1fa8c">range</span><span style="color:#999999">(</span>num<span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span>name<span style="color:#999999">)</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"跳舞..."</span><span style="color:#999999">)</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">0.5</span><span style="color:#999999">)</span><span style="color:#ff79c6">if</span> __name__ <span style="color:#6272a4">==</span> <span style="color:#f1fa8c">"__main__"</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"主进程的编号:"</span><span style="color:#999999">,</span> os<span style="color:#999999">.</span>getpid<span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#6272a4"># 2.使用进程类创建进程对象</span><span style="color:#6272a4"># args:使用元组方式给指定任务传参</span>sing_process <span style="color:#6272a4">=</span> multiprocessing<span style="color:#999999">.</span>Process<span style="color:#999999">(</span>target<span style="color:#6272a4">=</span>sing<span style="color:#999999">,</span> args<span style="color:#6272a4">=</span><span style="color:#999999">(</span><span style="color:#f1fa8c">3</span><span style="color:#999999">,</span> <span style="color:#f1fa8c">"李华"</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#6272a4"># kwargs:使用字典方式给指定任务传参</span>dance_process <span style="color:#6272a4">=</span> multiprocessing<span style="color:#999999">.</span>Process<span style="color:#999999">(</span>target<span style="color:#6272a4">=</span>dance<span style="color:#999999">,</span> kwargs<span style="color:#6272a4">=</span><span style="color:#999999">{</span><span style="color:#f1fa8c">"num"</span><span style="color:#999999">:</span> <span style="color:#f1fa8c">2</span><span style="color:#999999">,</span> <span style="color:#f1fa8c">"name"</span><span style="color:#999999">:</span><span style="color:#f1fa8c">"小明"</span><span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#6272a4"># 3.使用进程对象启动进程执行指定任务</span>sing_process<span style="color:#999999">.</span>start<span style="color:#999999">(</span><span style="color:#999999">)</span>dance_process<span style="color:#999999">.</span>start<span style="color:#999999">(</span><span style="color:#999999">)</span>
</code></span></span></span></span>
运行结果:
2.6 进程的注意事项:
(1)主进程会等待所有的子进程完成才结束:
如下图所示,打开QQ时会创建一个主进程,而QQ里面有两个子进程。主进程会等待所有的子进程完成才结束:
下面看一个例子:
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python"><span style="color:#ff79c6">import</span> time
<span style="color:#ff79c6">import</span> multiprocessing<span style="color:#ff79c6">def</span> <span style="color:#8be9fd">work</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#6272a4"># 子进程会工作2秒钟</span><span style="color:#ff79c6">for</span> i <span style="color:#ff79c6">in</span> <span style="color:#f1fa8c">range</span><span style="color:#999999">(</span><span style="color:#f1fa8c">10</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"工作中..."</span><span style="color:#999999">)</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">0.2</span><span style="color:#999999">)</span><span style="color:#ff79c6">if</span> __name__ <span style="color:#6272a4">==</span> <span style="color:#f1fa8c">"__main__"</span><span style="color:#999999">:</span>work_process <span style="color:#6272a4">=</span> multiprocessing<span style="color:#999999">.</span>Process<span style="color:#999999">(</span>target<span style="color:#6272a4">=</span>work<span style="color:#999999">)</span>work_process<span style="color:#999999">.</span>start<span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#6272a4"># 主进程睡眠1秒</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">1</span><span style="color:#999999">)</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"主进程执行完了..."</span><span style="color:#999999">)</span>
</code></span></span></span></span>
运行结果:
我们发现,虽然打印了主进程执行完了,但是程序还没有结束,这就说明:主进程会等待所有的子进程完成才结束。
但是我们都知道,当我们把QQ的主进程关闭时,子进程都结束了。那怎么做才能当主进程结束时,子进程也结束了呢?
(2)设置守护主进程:
这个就是说,每一个子进程都守护主进程,当主进程结束了之后,子进程直接结束,也就是被销毁。
只需要加一句话:
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python">work_process<span style="color:#999999">.</span>daemon <span style="color:#6272a4">=</span> <span style="color:#8be9fd">True</span> <span style="color:#6272a4"># 设置子进程 守护 主进程</span>
</code></span></span></span></span>
看个完整的例子:
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python"><span style="color:#ff79c6">import</span> time
<span style="color:#ff79c6">import</span> multiprocessing<span style="color:#ff79c6">def</span> <span style="color:#8be9fd">work</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#6272a4"># 子进程会工作2秒钟</span><span style="color:#ff79c6">for</span> i <span style="color:#ff79c6">in</span> <span style="color:#f1fa8c">range</span><span style="color:#999999">(</span><span style="color:#f1fa8c">10</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"工作中..."</span><span style="color:#999999">)</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">0.2</span><span style="color:#999999">)</span><span style="color:#ff79c6">if</span> __name__ <span style="color:#6272a4">==</span> <span style="color:#f1fa8c">"__main__"</span><span style="color:#999999">:</span>work_process <span style="color:#6272a4">=</span> multiprocessing<span style="color:#999999">.</span>Process<span style="color:#999999">(</span>target<span style="color:#6272a4">=</span>work<span style="color:#999999">)</span>work_process<span style="color:#999999">.</span>daemon <span style="color:#6272a4">=</span> <span style="color:#8be9fd">True</span> <span style="color:#6272a4"># 设置子进程 守护 主进程</span>work_process<span style="color:#999999">.</span>start<span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#6272a4"># 主进程睡眠1秒</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">1</span><span style="color:#999999">)</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"主进程执行完了..."</span><span style="color:#999999">)</span>
</code></span></span></span></span>
运行结果:
2.7 多进程-案例:
(1)需求分析:
(2)实现步骤:
(3)文件的拷贝函数实现步骤:
(4)实现代码:
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python"><span style="color:#ff79c6">import</span> os
<span style="color:#ff79c6">import</span> multiprocessing<span style="color:#ff79c6">def</span> <span style="color:#8be9fd">copy_file</span><span style="color:#999999">(</span>file_name<span style="color:#999999">,</span> source_dir<span style="color:#999999">,</span> dest_dir<span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#6272a4"># 1.拼接源文件路径和目标文件路径</span>source_path <span style="color:#6272a4">=</span> source_dir <span style="color:#6272a4">+</span> <span style="color:#f1fa8c">"/"</span> <span style="color:#6272a4">+</span> file_namedest_path <span style="color:#6272a4">=</span> dest_dir <span style="color:#6272a4">+</span> <span style="color:#f1fa8c">"/"</span> <span style="color:#6272a4">+</span> file_name<span style="color:#6272a4"># 2.打开源文件和目标文件</span><span style="color:#ff79c6">with</span> <span style="color:#f1fa8c">open</span><span style="color:#999999">(</span>source_path<span style="color:#999999">,</span> <span style="color:#f1fa8c">"rb"</span><span style="color:#999999">)</span> <span style="color:#ff79c6">as</span> source_file<span style="color:#999999">:</span><span style="color:#ff79c6">with</span> <span style="color:#f1fa8c">open</span><span style="color:#999999">(</span>dest_path<span style="color:#999999">,</span> <span style="color:#f1fa8c">"wb"</span><span style="color:#999999">)</span> <span style="color:#ff79c6">as</span> dest_file<span style="color:#999999">:</span><span style="color:#6272a4"># 3.循环读取源文件到目标文件</span><span style="color:#ff79c6">while</span> <span style="color:#8be9fd">True</span><span style="color:#999999">:</span>data <span style="color:#6272a4">=</span> source_file<span style="color:#999999">.</span>read<span style="color:#999999">(</span><span style="color:#f1fa8c">1024</span><span style="color:#999999">)</span><span style="color:#ff79c6">if</span> data<span style="color:#999999">:</span> <span style="color:#6272a4"># 没到文件的最后一行</span>dest_file<span style="color:#999999">.</span>write<span style="color:#999999">(</span>data<span style="color:#999999">)</span><span style="color:#ff79c6">else</span><span style="color:#999999">:</span> <span style="color:#6272a4"># 为空,则说明到最后一行</span><span style="color:#ff79c6">break</span><span style="color:#ff79c6">if</span> __name__ <span style="color:#6272a4">==</span> <span style="color:#f1fa8c">"__main__"</span><span style="color:#999999">:</span><span style="color:#6272a4"># 1.定义源文件夹和目标文件夹</span>source_dir <span style="color:#6272a4">=</span> r<span style="color:#f1fa8c">"python视频"</span>dest_dir <span style="color:#6272a4">=</span> r<span style="color:#f1fa8c">"/home/python/桌面/test"</span><span style="color:#6272a4"># 2.创建目标文件夹</span><span style="color:#ff79c6">try</span><span style="color:#999999">:</span>os<span style="color:#999999">.</span>mkdir<span style="color:#999999">(</span>dest_dir<span style="color:#999999">)</span><span style="color:#ff79c6">except</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"目标文件夹已经存在,未创建"</span><span style="color:#999999">)</span><span style="color:#6272a4"># 3.读取源文件的文件列表</span>file_list <span style="color:#6272a4">=</span> os<span style="color:#999999">.</span>listdir<span style="color:#999999">(</span>source_dir<span style="color:#999999">)</span><span style="color:#6272a4"># 4.遍历文件列表实现拷贝</span><span style="color:#ff79c6">for</span> file_name <span style="color:#ff79c6">in</span> file_list<span style="color:#999999">:</span><span style="color:#6272a4"># copy_file(file_name, source_dir,dest_dir) # 这个实现是单任务的拷贝</span><span style="color:#6272a4"># 5.使用多进程实现多任务拷贝</span>sub_process <span style="color:#6272a4">=</span> multiprocessing<span style="color:#999999">.</span>Process<span style="color:#999999">(</span>target<span style="color:#6272a4">=</span>copy_file<span style="color:#999999">,</span>args<span style="color:#6272a4">=</span><span style="color:#999999">(</span>file_name<span style="color:#999999">,</span> source_dir<span style="color:#999999">,</span> dest_dir<span style="color:#999999">)</span><span style="color:#999999">)</span>sub_process<span style="color:#999999">.</span>start<span style="color:#999999">(</span><span style="color:#999999">)</span>
</code></span></span></span></span>
三、线程:
3.1 线程的介绍:
进程是分配资源的最小单位,一旦创建一个进程就会分配一 定的资源,就像跟两个人聊QQ就需要打开两个QQ软件一样是比较浪费资源的。
线程是程序执行的最小单位,实际上进程只负责分配资源,而利用这些资源执行程序的是线程,也就说进程是线程的容器。一个进程中最少有一一个线程来负责执行程序,同时线程自己不拥有系统资源,只需要一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。这就像通过一个QQ软件(一个进程)打开两个窗口(两个线程)跟两个人聊天一样,实现多任务的同时也节省了资源。
3.2 多线程的作用:
将上图中的程序使用多线程实现,怎么做呢?为此我们先看一下,单线程是怎么实现的:
如下图,单线程是按照顺序实现的,也就是说进程中默认有一个线程用来执行程序,我们称之为主线程。
如何使用多线程实现呢?和前面的进程一样,用主线程执行func_a,再创建一个子线程执行func_b。
3.3 多线程实现多任务:
(1)线程的创建步骤:
- 1、导入线程包:
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python"><span style="color:#ff79c6">import</span> threading
</code></span></span></span></span>
- 2、通过线程类创建线程对象:
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python">线程对象 <span style="color:#6272a4">=</span> threading<span style="color:#999999">.</span>Thread<span style="color:#999999">(</span>target<span style="color:#6272a4">=</span>任务名<span style="color:#999999">)</span>
</code></span></span></span></span>
- 3、启动线程执行任务:
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python">线程对象<span style="color:#999999">.</span>start<span style="color:#999999">(</span><span style="color:#999999">)</span>
</code></span></span></span></span>
(2)多进程例子:
下面程序是单线程,先执行唱歌的函数,再执行跳舞的函数。需要3秒完成。
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python"><span style="color:#ff79c6">import</span> time<span style="color:#6272a4"># 唱歌</span>
<span style="color:#ff79c6">def</span> <span style="color:#8be9fd">sing</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">for</span> i <span style="color:#ff79c6">in</span> <span style="color:#f1fa8c">range</span><span style="color:#999999">(</span><span style="color:#f1fa8c">3</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"唱歌..."</span><span style="color:#999999">)</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">0.5</span><span style="color:#999999">)</span> <span style="color:#6272a4"># 延迟0.5秒</span>
<span style="color:#6272a4"># 跳舞</span>
<span style="color:#ff79c6">def</span> <span style="color:#8be9fd">dance</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">for</span> i <span style="color:#ff79c6">in</span> <span style="color:#f1fa8c">range</span><span style="color:#999999">(</span><span style="color:#f1fa8c">3</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"跳舞..."</span><span style="color:#999999">)</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">0.5</span><span style="color:#999999">)</span>
<span style="color:#ff79c6">if</span> __name__ <span style="color:#6272a4">==</span> <span style="color:#f1fa8c">"__main__"</span><span style="color:#999999">:</span>sing<span style="color:#999999">(</span><span style="color:#999999">)</span>dance<span style="color:#999999">(</span><span style="color:#999999">)</span>
</code></span></span></span></span>
运行结果:
上面的程序怎么使用多线程实现呢?下面的程序实现了多线程实现多任务,我们会发现,只需要1.5秒执行完了,唱歌和跳舞是交替执行的。
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python"><span style="color:#6272a4"># 1.导入进程包</span>
<span style="color:#ff79c6">import</span> time
<span style="color:#ff79c6">import</span> threading<span style="color:#6272a4"># 唱歌</span>
<span style="color:#ff79c6">def</span> <span style="color:#8be9fd">sing</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">for</span> i <span style="color:#ff79c6">in</span> <span style="color:#f1fa8c">range</span><span style="color:#999999">(</span><span style="color:#f1fa8c">3</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"唱歌..."</span><span style="color:#999999">)</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">0.5</span><span style="color:#999999">)</span> <span style="color:#6272a4"># 延迟0.5秒</span><span style="color:#6272a4"># 跳舞</span>
<span style="color:#ff79c6">def</span> <span style="color:#8be9fd">dance</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">for</span> i <span style="color:#ff79c6">in</span> <span style="color:#f1fa8c">range</span><span style="color:#999999">(</span><span style="color:#f1fa8c">3</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"跳舞..."</span><span style="color:#999999">)</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">0.5</span><span style="color:#999999">)</span><span style="color:#ff79c6">if</span> __name__ <span style="color:#6272a4">==</span> <span style="color:#f1fa8c">"__main__"</span><span style="color:#999999">:</span><span style="color:#6272a4"># 2.使用进程类创建进程对象</span>sing_thread <span style="color:#6272a4">=</span> threading<span style="color:#999999">.</span>Thread<span style="color:#999999">(</span>target<span style="color:#6272a4">=</span>sing<span style="color:#999999">)</span>dance_thread <span style="color:#6272a4">=</span> threading<span style="color:#999999">.</span>Thread<span style="color:#999999">(</span>target<span style="color:#6272a4">=</span>dance<span style="color:#999999">)</span><span style="color:#6272a4"># 3.使用进程对象启动进程执行指定任务</span>sing_thread<span style="color:#999999">.</span>start<span style="color:#999999">(</span><span style="color:#999999">)</span>dance_thread<span style="color:#999999">.</span>start<span style="color:#999999">(</span><span style="color:#999999">)</span>
</code></span></span></span></span>
运行结果:
3.4 线程执行带有参数的任务:
(1)参数说明:
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python">进程对象 <span style="color:#6272a4">=</span> threading<span style="color:#999999">.</span>Thread<span style="color:#999999">(</span>target<span style="color:#6272a4">=</span>任务名<span style="color:#999999">,</span> args<span style="color:#999999">,</span> kwargs<span style="color:#999999">)</span>
</code></span></span></span></span>
(2)例子:
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python"><span style="color:#6272a4"># 1.导入进程包</span>
<span style="color:#ff79c6">import</span> time
<span style="color:#ff79c6">import</span> threading<span style="color:#6272a4"># 唱歌</span>
<span style="color:#ff79c6">def</span> <span style="color:#8be9fd">sing</span><span style="color:#999999">(</span>num<span style="color:#999999">,</span> name<span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">for</span> i <span style="color:#ff79c6">in</span> <span style="color:#f1fa8c">range</span><span style="color:#999999">(</span>num<span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span>name<span style="color:#999999">)</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"唱歌..."</span><span style="color:#999999">)</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">0.5</span><span style="color:#999999">)</span> <span style="color:#6272a4"># 延迟0.5秒</span><span style="color:#6272a4"># 跳舞</span>
<span style="color:#ff79c6">def</span> <span style="color:#8be9fd">dance</span><span style="color:#999999">(</span>num<span style="color:#999999">,</span> name<span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">for</span> i <span style="color:#ff79c6">in</span> <span style="color:#f1fa8c">range</span><span style="color:#999999">(</span>num<span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span>name<span style="color:#999999">)</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"跳舞..."</span><span style="color:#999999">)</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">0.5</span><span style="color:#999999">)</span><span style="color:#ff79c6">if</span> __name__ <span style="color:#6272a4">==</span> <span style="color:#f1fa8c">"__main__"</span><span style="color:#999999">:</span><span style="color:#6272a4"># 2.使用进程类创建进程对象</span><span style="color:#6272a4"># args:使用元组方式给指定任务传参</span>sing_thread <span style="color:#6272a4">=</span> threading<span style="color:#999999">.</span>Thread<span style="color:#999999">(</span>target<span style="color:#6272a4">=</span>sing<span style="color:#999999">,</span> args<span style="color:#6272a4">=</span><span style="color:#999999">(</span><span style="color:#f1fa8c">3</span><span style="color:#999999">,</span> <span style="color:#f1fa8c">"李华"</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#6272a4"># kwargs:使用字典方式给指定任务传参</span>dance_thread <span style="color:#6272a4">=</span> threading<span style="color:#999999">.</span>Thread<span style="color:#999999">(</span>target<span style="color:#6272a4">=</span>dance<span style="color:#999999">,</span> kwargs<span style="color:#6272a4">=</span><span style="color:#999999">{</span><span style="color:#f1fa8c">"num"</span><span style="color:#999999">:</span> <span style="color:#f1fa8c">2</span><span style="color:#999999">,</span> <span style="color:#f1fa8c">"name"</span><span style="color:#999999">:</span><span style="color:#f1fa8c">"小明"</span><span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#6272a4"># 3.使用进程对象启动进程执行指定任务</span>sing_thread<span style="color:#999999">.</span>start<span style="color:#999999">(</span><span style="color:#999999">)</span>dance_thread<span style="color:#999999">.</span>start<span style="color:#999999">(</span><span style="color:#999999">)</span>
</code></span></span></span></span>
3.5 主线程和子线程的结束顺序:
(1)主线程会等待所有的子线程完成才结束:
下面的例子说明了主线程会等待所有的子线程完成才结束。
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python"><span style="color:#ff79c6">import</span> time
<span style="color:#ff79c6">import</span> threading<span style="color:#ff79c6">def</span> <span style="color:#8be9fd">work</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#6272a4"># 子进程会工作2秒钟</span><span style="color:#ff79c6">for</span> i <span style="color:#ff79c6">in</span> <span style="color:#f1fa8c">range</span><span style="color:#999999">(</span><span style="color:#f1fa8c">10</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"工作中..."</span><span style="color:#999999">)</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">0.2</span><span style="color:#999999">)</span><span style="color:#ff79c6">if</span> __name__ <span style="color:#6272a4">==</span> <span style="color:#f1fa8c">"__main__"</span><span style="color:#999999">:</span>work_thread <span style="color:#6272a4">=</span> threading<span style="color:#999999">.</span>Thread<span style="color:#999999">(</span>target<span style="color:#6272a4">=</span>work<span style="color:#999999">)</span>work_thread<span style="color:#999999">.</span>start<span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#6272a4"># 主进程睡眠1秒</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">1</span><span style="color:#999999">)</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"主线程执行完了..."</span><span style="color:#999999">)</span>
</code></span></span></span></span>
运行结果:
我们发现,虽然打印了主线程执行完了,但是程序还没有结束,这就说明:主线程会等待所有的子线程完成才结束。
但是我们希望主线程结束了,则所有的子线程都结束,那怎么做呢?接着看:
(2)设置守护主线程:
- 方法一:
只需要加一句话:
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python">work_process<span style="color:#999999">.</span>daemon <span style="color:#6272a4">=</span> <span style="color:#8be9fd">True</span> <span style="color:#6272a4"># 设置子线程 守护 主进程</span>
</code></span></span></span></span>
- 方法二:
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python">work_thread <span style="color:#6272a4">=</span> threading<span style="color:#999999">.</span>Thread<span style="color:#999999">(</span>target<span style="color:#6272a4">=</span>work<span style="color:#999999">,</span> daemon<span style="color:#6272a4">=</span><span style="color:#8be9fd">True</span><span style="color:#999999">)</span> <span style="color:#6272a4"># 设置子线程 守护 主进程</span>
</code></span></span></span></span>
看个完整的例子:
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python"><span style="color:#ff79c6">import</span> time
<span style="color:#ff79c6">import</span> threading<span style="color:#ff79c6">def</span> <span style="color:#8be9fd">work</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#6272a4"># 子进程会工作2秒钟</span><span style="color:#ff79c6">for</span> i <span style="color:#ff79c6">in</span> <span style="color:#f1fa8c">range</span><span style="color:#999999">(</span><span style="color:#f1fa8c">10</span><span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"工作中..."</span><span style="color:#999999">)</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">0.2</span><span style="color:#999999">)</span><span style="color:#ff79c6">if</span> __name__ <span style="color:#6272a4">==</span> <span style="color:#f1fa8c">"__main__"</span><span style="color:#999999">:</span><span style="color:#6272a4"># 方法一:</span>work_thread <span style="color:#6272a4">=</span> threading<span style="color:#999999">.</span>Thread<span style="color:#999999">(</span>target<span style="color:#6272a4">=</span>work<span style="color:#999999">,</span> daemon<span style="color:#6272a4">=</span><span style="color:#8be9fd">True</span><span style="color:#999999">)</span> <span style="color:#6272a4"># 设置子进程 守护 主进程</span><span style="color:#6272a4"># 方法二:</span>work_thread<span style="color:#999999">.</span>daemon <span style="color:#6272a4">=</span> <span style="color:#8be9fd">True</span> <span style="color:#6272a4"># 设置子进程 守护 主进程</span>work_thread<span style="color:#999999">.</span>start<span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#6272a4"># 主进程睡眠1秒</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">1</span><span style="color:#999999">)</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"主线程执行完了..."</span><span style="color:#999999">)</span>
</code></span></span></span></span>
运行结果:
3.6 线程间的执行顺序:
(1)线程间的执行是无序的:
下图是一个进程创建的三个线程,这三个线程的执行顺序是无序的,与创建的顺序无关,它与操作系统的调度有关。
看一个例子:
(2)例子:
我们发现,运行的结果和线程的创建顺序并不一样,所以证明:线程间的执行是无序的。
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python"><span style="color:#ff79c6">import</span> threading
<span style="color:#ff79c6">import</span> time<span style="color:#ff79c6">def</span> <span style="color:#8be9fd">task</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">:</span>time<span style="color:#999999">.</span>sleep<span style="color:#999999">(</span><span style="color:#f1fa8c">1</span><span style="color:#999999">)</span> <span style="color:#6272a4"># 延迟一秒</span><span style="color:#6272a4"># current_thread:获取当前线程的对象</span>thread <span style="color:#6272a4">=</span> threading<span style="color:#999999">.</span>current_thread<span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#6272a4"># 获取当前的线程</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span>thread<span style="color:#999999">)</span><span style="color:#ff79c6">if</span> __name__ <span style="color:#6272a4">==</span> <span style="color:#f1fa8c">"__main__"</span><span style="color:#999999">:</span><span style="color:#ff79c6">for</span> i <span style="color:#ff79c6">in</span> <span style="color:#f1fa8c">range</span><span style="color:#999999">(</span><span style="color:#f1fa8c">5</span><span style="color:#999999">)</span><span style="color:#999999">:</span> <span style="color:#6272a4"># 创建5个线程</span>sub_thread <span style="color:#6272a4">=</span> threading<span style="color:#999999">.</span>Thread<span style="color:#999999">(</span>target<span style="color:#6272a4">=</span>task<span style="color:#999999">)</span>sub_thread<span style="color:#999999">.</span>start<span style="color:#999999">(</span><span style="color:#999999">)</span>
</code></span></span></span></span>
运行结果:
3.7 多线程-案例:
(1)需求分析:
(2)实现:
由于实现的步骤和多进程是一样的,所有接下来直接看代码,注释在代码中:
<span style="color:rgba(0, 0, 0, 0.75)"><span style="background-color:#ffffff"><span style="color:#000000"><span style="background-color:#282a36"><code class="language-python"><span style="color:#ff79c6">import</span> os
<span style="color:#ff79c6">import</span> threading
<span style="color:#ff79c6">def</span> <span style="color:#8be9fd">copy_file</span><span style="color:#999999">(</span>file_name<span style="color:#999999">,</span> source_dir<span style="color:#999999">,</span> dest_dir<span style="color:#999999">)</span><span style="color:#999999">:</span><span style="color:#6272a4"># 1.拼接源文件路径和目标文件路径</span>source_path <span style="color:#6272a4">=</span> source_dir <span style="color:#6272a4">+</span> <span style="color:#f1fa8c">"/"</span> <span style="color:#6272a4">+</span> file_namedest_path <span style="color:#6272a4">=</span> dest_dir <span style="color:#6272a4">+</span> <span style="color:#f1fa8c">"/"</span> <span style="color:#6272a4">+</span> file_name<span style="color:#6272a4"># 2.打开源文件和目标文件</span><span style="color:#ff79c6">with</span> <span style="color:#f1fa8c">open</span><span style="color:#999999">(</span>source_path<span style="color:#999999">,</span> <span style="color:#f1fa8c">"rb"</span><span style="color:#999999">)</span> <span style="color:#ff79c6">as</span> source_file<span style="color:#999999">:</span><span style="color:#ff79c6">with</span> <span style="color:#f1fa8c">open</span><span style="color:#999999">(</span>dest_path<span style="color:#999999">,</span> <span style="color:#f1fa8c">"wb"</span><span style="color:#999999">)</span> <span style="color:#ff79c6">as</span> dest_file<span style="color:#999999">:</span><span style="color:#6272a4"># 3.循环读取源文件到目标文件</span><span style="color:#ff79c6">while</span> <span style="color:#8be9fd">True</span><span style="color:#999999">:</span>data <span style="color:#6272a4">=</span> source_file<span style="color:#999999">.</span>read<span style="color:#999999">(</span><span style="color:#f1fa8c">1024</span><span style="color:#999999">)</span><span style="color:#ff79c6">if</span> data<span style="color:#999999">:</span> <span style="color:#6272a4"># 没到文件的最后一行</span>dest_file<span style="color:#999999">.</span>write<span style="color:#999999">(</span>data<span style="color:#999999">)</span><span style="color:#ff79c6">else</span><span style="color:#999999">:</span> <span style="color:#6272a4"># 为空,则说明到最后一行</span><span style="color:#ff79c6">break</span><span style="color:#ff79c6">if</span> __name__ <span style="color:#6272a4">==</span> <span style="color:#f1fa8c">"__main__"</span><span style="color:#999999">:</span><span style="color:#6272a4"># 1.定义源文件夹和目标文件夹</span>source_dir <span style="color:#6272a4">=</span> r<span style="color:#f1fa8c">"python视频"</span>dest_dir <span style="color:#6272a4">=</span> r<span style="color:#f1fa8c">"/home/python/桌面/test"</span><span style="color:#6272a4"># 2.创建目标文件夹</span><span style="color:#ff79c6">try</span><span style="color:#999999">:</span>os<span style="color:#999999">.</span>mkdir<span style="color:#999999">(</span>dest_dir<span style="color:#999999">)</span><span style="color:#ff79c6">except</span><span style="color:#999999">:</span><span style="color:#ff79c6">print</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"目标文件夹已经存在,未创建"</span><span style="color:#999999">)</span><span style="color:#6272a4"># 3.读取源文件的文件列表</span>file_list <span style="color:#6272a4">=</span> os<span style="color:#999999">.</span>listdir<span style="color:#999999">(</span>source_dir<span style="color:#999999">)</span><span style="color:#6272a4"># 4.遍历文件列表实现拷贝</span><span style="color:#ff79c6">for</span> file_name <span style="color:#ff79c6">in</span> file_list<span style="color:#999999">:</span><span style="color:#6272a4"># copy_file(file_name, source_dir,dest_dir) # 这个实现是单任务的拷贝</span><span style="color:#6272a4"># 5.使用多线程实现多任务拷贝</span>sub_thread <span style="color:#6272a4">=</span> threading<span style="color:#999999">.</span>Thread<span style="color:#999999">(</span>target<span style="color:#6272a4">=</span>copy_file<span style="color:#999999">,</span>args<span style="color:#6272a4">=</span><span style="color:#999999">(</span>file_name<span style="color:#999999">,</span> source_dir<span style="color:#999999">,</span> dest_dir<span style="color:#999999">)</span><span style="color:#999999">)</span>sub_thread<span style="color:#999999">.</span>start<span style="color:#999999">(</span><span style="color:#999999">)</span>
</code></span></span></span></span>
四、进程和线程对比:
4.1 关系对比:
4.2 区别对比:
4.3 优缺点对比:
相关文章:

python多任务
一、多任务 1.1 概念 多任务就是指:同一时间能执行多个任务。比方我们的电脑能一边QQ聊天,一边写论文,还能听歌。 1.2 多任务的优势: 多任务的最大好处是 充分利用CPU资源,提高程序的执行效率。 1.3 多任务的两种表…...
c语言 - inline关键字(内联函数)
概念 在编程中,inline是一个关键字,用于修饰函数。inline函数是一种对编译器的提示,表示这个函数在编译时应该进行内联展开。 内联展开是指将函数的代码插入到调用该函数的地方,而不是通过函数调用的方式执行。这样可以减少函数调…...
如何在Ubuntu 18.04上安装PHP 7.4并搭建本地开发环境
引言 PHP是一种流行的服务器脚本语言,用于创建动态和交互式web页面。开始使用你选择的语言是学习编程的第一步。 本教程将指导您在Ubuntu上安装PHP 7.4,并通过命令行设置本地编程环境。您还将安装依赖管理器Composer,并通过运行脚本来测试您…...
狭义相对论
文章目录 一、为什么光速不变?二、为什么爱因斯坦坚信“相对性原理”三、逻辑和数学显威力,狭义相对论时空变换(洛伦兹变换)推导四、新时空变换带来的新时空观1、有关相对论时间的“傻问题”2、关于相对论的“怪问题”3、关于“双…...

仓库使用综合练习
目录 1、使用mysql:5.6和 owncloud 镜像,构建一个个人网盘。 2、安装搭建私有仓库 Harbor 3、编写Dockerfile制作Web应用系统nginx镜像,生成镜像nginx:v1.1,并推送其到私有仓库。 4、Dockerfile快速搭建自己专属的LAMP环境,生…...

如何在前端实现WebSocket发送和接收TCP消息(多线程模式)
目录 第一步:创建WebSocket连接第二步:监听WebSocket事件第三步:发送消息第四步:后端处理函数说明 当在前端实现WebSocket发送和接收TCP消息时,可以使用以下步骤来实现多线程模式。本文将详细介绍如何在前端实现WebSoc…...

VB.NET通过VB6 ActiveX DLL调用PowerBasic及FreeBasic动态库
前面说的Delphi通过Activex DLL同时调用PowerBasic和FreeBasic写的DLL,是在WINDOWS基础平台上完成的。 而 .NET平台是架在WINDOWS基础平台之上的,它的上面VB.NET或C#等开发的APP程序,下面写一下用VB.NET,通过VB6注册的Activex DLL…...
怎样不引入图片实现前端css实现x关闭按钮
首先初始化一个dom节点 <span class"closeButton"></span>设置样式 .closeButton {width: 12px;height: 12px;margin-top: 5px;margin-right: 5px;float: right;cursor: pointer;color: #105c86;}通过伪元素before after画两条线 margin-left 的设置是…...
SpringBoot实现文件下载的多种方式
SpringBoot实现文件下载的几种方式 1. 将文件以流的形式一次性读取到内存,通过响应输出流输出到前端1.1 下载文件 2. 将输入流中的数据循环写入到响应输出流中,而不是一次性读取到内存,通过响应输出流输出到前端3. 下载网络文件到本地4. 网络…...
uniapp简单版语音播放
mounted() {this.ScanAudio(http://118.178.137.235:88/ipoker.mp3, 3); // 开始播放音频},ScanAudio(url, count) {// 递归终止条件:当循环次数小于等于 0 时,停止递归if (count < 0) return;// 创建内部音频上下文对象var music uni.createInnerAu…...

前端三剑客入门一文解决
文章目录 HTML快速开发网站Flask页面结构标签基础标签超链接图片列表下拉框表格input系列多行文本form表单 网络请求HTML案例 CSSCSS盒模型CSS样式定义CSS选择器 CSS样式使用1. 在标签上直接写2. 在head标签中写3.写到css文件中 标签样式1. 高度和宽度2. 块级和行内标签3.字体设…...
php curl apache 超时 500错误
web请求超过40s 就返回500错误 php的超时时间 set_time_limit无效 curl CURLOPT_TIMEOUT 设置请求时间 无效 设置apache Timeout 链接超时 无效 最后添加 Fcgid才可以 apache 配置文件 httpd.conf <IfModule mod_fcgid.c>FcgidProcessLifeTime 10000FcgidIOTimeout 1000…...
ValueError: too many values to unpack (expected 4)
ValueError: too many values to unpack (expected 4)这个错误通常是由于解包赋值个数与返回值个数不匹配所致。 比较常见的情况是: 1.在数据预处理函数中,使用train_test_split对数据进行分割后返回值,但解包赋值时个数与返回值不匹配。 train_test_split返回的就是(X_trai…...
学习Vue过程中遇到的问题汇总
Vue 控制台出现You are running Vue in development mode. Make sure to turn on production mode when deploying for production. 在页面的body标签或head标签中加入如下代码 <script type"text/javascript">Vue.config.productionTip false</script>…...
cloud_mall-notes03
请求方式GetMapping(11)用途方法返回值GetMapping(“info”)查询管理员信息getByIdsysUserGetMapping(“info/{userId}”)查询管理员详情getByIdsysUserGetMapping(“info/{roleId}”)查询角色详情getByIdsysRoleGetMapping(“info/{categoryId}”)根据标…...
Redis注入中出现的问题
Redis注入中出现的问题 出现的问题 Error starting ApplicationContext. To display the conditions report re-run your application with debug enabled. 2023-08-23 16:38:42.294 ERROR 32136 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter : *********…...

机器学习实战之模型的解释性:Scikit-Learn的SHAP和LIME库详解
引言:机器学习模型的“黑箱”困境 机器学习模型的崛起让我们惊叹不已!不论是预测房价、识别图片中的猫狗,还是推荐给你喜欢的音乐,这些模型都表现得非常出色。但是,有没有想过,这些模型到底是如何做出这些决…...

【网络安全】防火墙知识点全面图解(二)
本系列文章包含: 【网络安全】防火墙知识点全面图解(一)【网络安全】防火墙知识点全面图解(二) 防火墙知识点全面图解(二) 21、路由器的访问控制列表是什么样的?22、防火墙的安全策…...
【计算机视觉 | 目标检测】arxiv 计算机视觉关于目标检测的学术速递(8 月 14 日论文合集)
文章目录 一、检测相关(7篇)1.1 Continual Face Forgery Detection via Historical Distribution Preserving1.2 Exploring Predicate Visual Context in Detecting of Human-Object Interactions1.3 Out-of-Distribution Detection for Monocular Depth Estimation1.4 Cyclic-…...

自学设计模式(类图、设计原则、单例模式 - 饿汉/懒汉)
设计模式需要用到面向对象的三大特性——封装、继承、多态(同名函数具有不同的状态) UML类图 eg.—— 描述类之间的关系(设计程序之间画类图) : public; #: protected; -: private; 下划线: static 属性名:类型(默认值…...

RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...

深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

springboot 日志类切面,接口成功记录日志,失败不记录
springboot 日志类切面,接口成功记录日志,失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...

渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...
TJCTF 2025
还以为是天津的。这个比较容易,虽然绕了点弯,可还是把CP AK了,不过我会的别人也会,还是没啥名次。记录一下吧。 Crypto bacon-bits with open(flag.txt) as f: flag f.read().strip() with open(text.txt) as t: text t.read…...