2017-09-25 62 views
1

执行顺序这是一个测试Threading代码:的Python:在线程

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继续出现在第一个地方......据我所知,thre的执行顺序广告是随机的,对吧?

我的代码有什么问题?

回答

1

线程0先开始,抓住锁,然后睡觉,而持有锁的是。睡眠结束之间有一个非常短的时间,因为退出with模块而获得锁定,并且循环再次获得锁定,因此线程0将再次获得锁定的机会非常好......并且再一次,直到episode < 5终于是错误的。

删除time.sleep(1)上的缩进级别,使其作为循环的一部分执行,而不是作为with块的一部分执行。然后,线程0将在开始其睡眠之前释放锁,而其他线程几乎肯定会在线程0正在休眠时获得锁(他们有一秒钟的时间来完成,而不是远低于眨眼)。

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 
+0

我不认为这应该是@Unni所以你能指望一个答案 – Unni

+0

? – Sraw

+0

我觉得它应该是一个评论,说你在执行时会得到不同的输出。我没有看到这个答案贡献任何知识。至少对产出的解释仍然是一项宝贵的贡献。 – Unni