<h2>螺纹可停止功能</h2>
<p>可以修改函数以允许
停在旗子旁边。</p>
<p>我们需要一个对象,可以访问running函数,并将标志设置为stop running。</p>
<p>我们可以使用<code>threading.currentThread()</code>对象。</p>
<pre><code>import threading
import time
def doit(arg):
t = threading.currentThread()
while getattr(t, "do_run", True):
print ("working on %s" % arg)
time.sleep(1)
print("Stopping as you wish.")
def main():
t = threading.Thread(target=doit, args=("task",))
t.start()
time.sleep(5)
t.do_run = False
t.join()
if __name__ == "__main__":
main()
</code></pre>
<p>诀窍是,正在运行的线程可以附加其他属性。解决方案构建
基于假设:</p>
<ul>
<li>线程具有默认值为<code>True</code>的属性“do_run”</li>
<li>驱动父进程可以将属性“do_run”分配给启动的线程<code>False</code>。</li>
</ul>
<p>运行代码,我们得到以下输出:</p>
<pre><code>$ python stopthread.py
working on task
working on task
working on task
working on task
working on task
Stopping as you wish.
</code></pre>
<h2>使用避孕药事件</h2>
<p>另一种选择是使用<code>threading.Event</code>作为函数参数。它是由
默认值为<code>False</code>,但是外部进程可以“设置”(设置为<code>True</code>),函数可以
使用<code>wait(timeout)</code>函数了解它。</p>
<p>我们可以在零超时的情况下<code>wait</code>,但我们也可以将其用作睡眠计时器(下面使用)。</p>
<pre><code>def doit(stop_event, arg):
while not stop_event.wait(1):
print ("working on %s" % arg)
print("Stopping as you wish.")
def main():
pill2kill = threading.Event()
t = threading.Thread(target=doit, args=(pill2kill, "task"))
t.start()
time.sleep(5)
pill2kill.set()
t.join()
</code></pre>
<p>编辑:我在Python3.6中尝试过。<code>stop_event.wait()</code>阻止事件(以及while循环)直到释放。它不返回布尔值。而使用<code>stop_event.is_set()</code>则有效。</p>
<h2>一丸多线停</h2>
<p>如果我们必须停止多个线程,那么可以更好地看到药丸的优势
立刻,就像一颗药丸对所有人都有效一样。</p>
<p><code>doit</code>根本不会改变,只有<code>main</code>处理线程有点不同。</p>
<pre><code>def main():
pill2kill = threading.Event()
tasks = ["task ONE", "task TWO", "task THREE"]
def thread_gen(pill2kill, tasks):
for task in tasks:
t = threading.Thread(target=doit, args=(pill2kill, task))
yield t
threads = list(thread_gen(pill2kill, tasks))
for thread in threads:
thread.start()
time.sleep(5)
pill2kill.set()
for thread in threads:
thread.join()
</code></pre>