Python:线程中的执行顺序

时间:2017-09-25 03:43:59

标签: python multithreading

这是用于测试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会一直连续出现......据我所知,线程的执行顺序是随机的,对吗?

我的代码有什么问题?

2 个答案:

答案 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