[英]How to run two functions in parallel with threading in Python?
我想并行运行两个函数,它们并行打印两个列表。 但是我得到的是一个列表,在另一个列表完成后打印出来。
我尝试了以下代码。
import threading
import time
def fun1():
testz=['z','y','x','w','v','u','t']
for j in testz:
print (j)
time.sleep(1)
def fun2():
test=['a','b','c','d','e','f','g']
for i in test:
print (i)
time.sleep(1)
thread1 = threading.Thread(target=fun1())
thread2 = threading.Thread(target=fun2())
thread1.start()
time.sleep(0.5)
thread2.start()
thread1.join()
thread2.join()
我期望的结果是:
z
a
y
b
x
c
w
d
v
e
u
f
t
g
但是我得到的是:
z
y
x
w
v
u
t
a
b
c
d
e
f
g
似乎两个线程正在一个接一个地运行。
问题是您在主线程而不是子线程中运行函数。 您首先调用函数,然后再将返回的值作为线程目标。 您的代码应为:
thread1 = threading.Thread(target=fun1)
thread2 = threading.Thread(target=fun2)
然后您将获得预期的结果。
如果以交互方式运行代码,将获得以下输出
>>> import threading
>>> import time
>>>
>>> def fun1():
... testz=['z','y','x','w','v','u','t']
... for j in testz:
... print (j)
... time.sleep(1)
...
>>> def fun2():
... test=['a','b','c','d','e','f','g']
... for i in test:
... print (i)
... time.sleep(1)
...
>>>
>>> thread1 = threading.Thread(target=fun1())
z
y
x
w
v
u
t
>>> thread2 = threading.Thread(target=fun2())
a
b
c
d
e
f
g
>>>
>>> thread1.start()
>>> time.sleep(0.5)
>>> thread2.start()
>>>
>>> thread1.join()
>>> thread2.join()
您可以看到,一旦使用thread1 = threading.Thread(target=fun1())
为fun1()
创建线程,就会执行fun1()
。
同样,为fun2()
创建线程后,将立即执行该线程。
因此,这两个功能实际上并未并行运行,而您正在获得该输出。
在创建线程时,您将fun1
/ fun2
的结果作为目标而不是函数本身传递。 这就是为什么立即而不是在启动线程之后立即执行功能的原因。
尝试将您的线程创建替换为
thread1 = threading.Thread(target=fun1)
thread2 = threading.Thread(target=fun2)
您的代码存在以下问题:
thread1 = threading.Thread(target=fun1())
thread2 = threading.Thread(target=fun2())
在这里,它在主线程本身中被称为整体函数。 也就是说,两个函数都使用相同的threadID调用
<_MainThread(MainThread, started 4339086784)>
z
y
x
w
v
u
t
<_MainThread(MainThread, started 4339086784)>
a
b
c
d
e
f
g
正确地,用于创建线程对象的语法应为:
thread1 = threading.Thread(target=fun1)
thread2 = threading.Thread(target=fun2)
更改后:输出
z
a
y
b
x
c
w
d
v
e
u
f
t
g
线程处理不会使代码并行运行,而是提供了并行运行代码的错觉。 这属于并发的更大范围。
您正在创建两个线程。 线程将完成某些工作,并且操作系统可以随时将其关闭以将资源提供给另一个线程。 然后停止另一个线程,并继续第一个线程。 它将随机地执行此操作。
这些列表的打印元素发生得如此之快,以至于操作系统从未停止过该线程。 另外,请注意,使用螺纹打印可能会导致竞争。 从本质上讲,奇怪的行为可能很难调试。 做一些模糊测试,基本上为每个迭代添加一个带有随机数的sleep
, sleep(random.random())
,您将看到这些竞争条件变得活跃起来。
如果要在问题中说明文字输出,可以执行以下操作:
from itertools import chain
for i in chain(*zip(list1, list2)):
print(i)
您的第一个线程先结束,然后再开始第二个线程,因为您在那里已经睡着了,并且正在执行功能。 您应该将callable传递给线程(传递不带()的函数)。 您不能保证您的代码将按预期运行,并在每次执行中获得相同的结果。
如果不需要线程,则可以使用简单的zip:
for a, b in zip(list1, list2):
print(a)
print(b)
如果您确实需要多线程并且依次执行elist的每个元素,则可以查看Condition()来锁定线程,并使用acquire()和release()方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.