2017-09-25 32 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