<p>你已经得到了你的具体案例的有效答案。但是,如果您更喜欢一个更通用的解决方案来解决更一般的问题,那么几乎没有不同的方法可以实现这一点。在</p>
<p>让我们定义一个问题:我想调度一个任务,准备一些资源给工作线程,然后在主线程中等待资源准备就绪。资源的准备只进行一次。当然,仍然有一个有效的问题:为什么我们不能在一个线程中按顺序运行所有的东西?但是让我们把这看作是一个介绍多线程世界的练习。在</p>
<p>下面是一些基本的python代码:</p>
<pre><code>import threading
import time
import random
data_ready=False
def do_sth():
global data_ready
def prepare_sth():
global data_ready
print("preparing, simulated by random wait")
time.sleep(random.randrange(5,10))
data_ready=True
print("resource is ready")
print("do_sth");
thr = threading.Thread(target=prepare_sth)
thr.start()
# WAIT HERE
if data_ready:
print("OK")
else:
print("ERROR")
do_sth()
</code></pre>
<p>当然,它并不像预期的那样工作,并且在输出的某个地方会有一条<code>ERROR</code>消息。但我们可以把问题改成:<em>什么取代了<code>WAIT HERE</code>?</em></p>
<p>解决此类问题最明显也是最糟糕的方法是主动等待:</p>
^{pr2}$
<p>尝试运行这段代码并观察(在Linux上使用<code>top</code>)CPU使用情况。你会注意到它在等待中长大。所以,请不要在现实生活中做这样的事情。在</p>
<p>规定资源准备只进行一次。所以,工作线程可以准备数据,然后我们可以等待这个线程在主线程中完成。在这种情况下,这是我的首选解决方案。在</p>
<pre><code>thr.join()
</code></pre>
<p>最后,使用一个完整的锁和条件变量方案。它需要更多的更改,因此完整的代码粘贴在这里:</p>
<pre><code>import threading
import time
import random
data_ready=False
def do_sth():
global data_ready
lock=threading.Lock()
cond=threading.Condition(lock)
def prepare_sth():
global data_ready
with cond:
print("preparing, simulated by random wait")
time.sleep(random.randrange(5,10))
data_ready=True
print("resource is ready")
cond.notify()
print("do_sth");
with cond:
thr = threading.Thread(target=prepare_sth)
thr.start()
while not data_ready:
print("waiting")
cond.wait()
if data_ready:
print("OK")
else:
print("ERROR")
do_sth()
</code></pre>
<p>如果您需要在一个线程中以循环方式准备资源(例如,一些数据),并在另一个线程中使用它,这将是一种合适的方法。请查找<em>生产者-消费者模型</em>。在</p>
<p>最后但并非最不重要。我为<code>global</code>变量使用了<code>global</code>说明符,因为我很懒,而且这个例子是关于不同的东西的。但是,把它看作是一个糟糕的设计。变量只能在<code>do_sth</code>和<code>prepare_sth</code>线程之间共享。您可以使用<code>args</code>和<code>kwargs</code>方法的参数。在</p>