这是用于测试Threading
的代码:
import threading
import time
episode = 0
lock = threading.Lock()
class Agent(threading.Thread):
def __init__(self, id):
threading.Thread.__init__(self)
self.id = id
def run(self):
global episode
while episode < 5:
with lock:
print(
"{} : episode will be changed {} -> {}".format(
self.id,
episode,
episode+1
)
)
episode += 1
print("{} : changed value -> {}".format(self.id, episode))
time.sleep(1)
if __name__ == "__main__":
agents = []
for i in range(3):
agents.append(Agent(i))
for agent in agents:
agent.start()
结果:
0 : episode will be changed 0 -> 1
0 : changed value -> 1
0 : episode will be changed 1 -> 2
0 : changed value -> 2
0 : episode will be changed 2 -> 3
0 : changed value -> 3
0 : episode will be changed 3 -> 4
0 : changed value -> 4
0 : episode will be changed 4 -> 5
0 : changed value -> 5
1 : episode will be changed 5 -> 6
1 : changed value -> 6
2 : episode will be changed 6 -> 7
2 : changed value -> 7
这是我预期的结果之一:
0 : episode will be changed 0 -> 1
0 : changed value -> 1
2 : episode will be changed 1 -> 2
2 : changed value -> 2
1 : episode will be changed 2 -> 3
1 : changed value -> 3
2 : episode will be changed 3 -> 4
2 : changed value -> 4
0 : episode will be changed 4 -> 5
0 : changed value -> 5
.
.
我无法理解为什么线程id = 0会一直连续出现......据我所知,线程的执行顺序是随机的,对吗?
我的代码有什么问题?
答案 0 :(得分:1)
线程0首先启动,抓取锁定,并在持有锁定时休眠。在睡眠结束之间有一段非常短的时间,由于退出with
块而导致锁被释放,并且循环再次获得锁定,因此线程0再次获得锁定的机会非常好......再一次,直到episode < 5
最终为假。
删除time.sleep(1)
上的缩进级别,使其作为循环的一部分执行,而不是作为with
块的一部分执行。然后线程0将在开始睡眠之前释放锁,并且其他线程几乎肯定会在线程0正在休眠时获得锁定(他们有一整秒时间这样做,而不是远远小于眨眼)。
答案 1 :(得分:1)
你真不走运?我测试了你的代码而没有改变任何东西,得到了以下输出:
0 : episode will be changed 0 -> 1
0 : changed value -> 1
1 : episode will be changed 1 -> 2
1 : changed value -> 2
2 : episode will be changed 2 -> 3
2 : changed value -> 3
2 : episode will be changed 3 -> 4
2 : changed value -> 4
2 : episode will be changed 4 -> 5
2 : changed value -> 5
0 : episode will be changed 5 -> 6
0 : changed value -> 6
1 : episode will be changed 6 -> 7
1 : changed value -> 7