這個Python代碼線程安全嗎?

[英]Is this Python code thread safe?


import time
import threading

class test(threading.Thread):
    def __init__ (self):
      threading.Thread.__init__(self)
      self.doSkip = False
      self.count = 0

    def run(self):
      while self.count<9:
         self.work()

    def skip(self):
      self.doSkip = True

    def work(self):
      self.count+=1
      time.sleep(1)
      if(self.doSkip):
        print "skipped"
        self.doSkip = False
        return
      print self.count

t = test()
t.start()
while t.count<9:
  time.sleep(2)
  t.skip()

5 个解决方案

#1


2  

Thread-safe in which way? I don't see any part you might want to protect here.

線程安全的方式?我沒看到你想要保護的地方。

skip may reset the doSkip at any time, so there's not much point in locking it. You don't have any resources that are accessed at the same time - so IMHO nothing can be corrupted / unsafe in this code.

skip可以在任何時候重置doSkip,因此鎖定它沒有什么意義。您沒有同時訪問的任何資源——因此,在此代碼中沒有任何東西可以被破壞或不安全。

The only part that might run differently depending on locking / counting is how many "skip"s do you expect on every call to .skip(). If you want to ensure that every skip results in a skipped call to .work(), you should change doSkip into a counter that is protected by a lock on both increment and compare/decrement. Currently one thread might turn doSkip on after the check, but before the doSkip reset. It doesn't matter in this example, but in some real situation (with more code) it might make a difference.

唯一可能會以不同方式運行的部分,取決於鎖定/計數,這是每次調用.skip()時所期望的“跳過”數。如果您想要確保每個skip都導致了一個跳過的調用。work(),您應該將doSkip更改為一個計數器,該計數器在增量和比較/減量上都受到鎖的保護。目前有一個線程可能在檢查后會返回doSkip,但是在doSkip重置之前。在這個例子中,這並不重要,但是在一些實際情況下(用更多的代碼),可能會有所不同。

#2


1  

Whenever the test of a mutex boolean ( e.g. if(self.doSkip) ) is separate from the set of the mutex boolean you will probably have threading problems.

每當對互斥體布爾值的測試(例如,如果(self。doskip))與mutex布爾值的集合分離時,您可能會遇到線程問題。

The rule is that your thread will get swapped out at the most inconvenient time. That is, after the test and before the set. Moving them closer together reduces the window for screw-ups but does not eliminate them. You almost always need a specially created mechanism from the language or kernel to fully close that window.

規則是您的線程將在最不方便的時間被交換。也就是說,在測試結束后,在設置之前,將它們移動到更近的地方,減少了屏幕的旋轉,但並沒有消除它們。您幾乎總是需要來自語言或內核的專門創建的機制來完全關閉該窗口。

The threading library has Semaphores that can be used to synchronize threads and/or create critical sections of code.

線程庫具有可用於同步線程和/或創建關鍵代碼段的信號量。

#3


0  

Apparently there isn't any critical resource, so I'd say it's thread-safe.

顯然沒有任何關鍵資源,所以我認為它是線程安全的。

But as usual you can't predict in which order the two threads will be blocked/run by the scheduler.

但是像往常一樣,您不能預測兩個線程將被調度程序阻塞/運行。

#4


0  

This is and will thread safe as long as you don't share data between threads.

只要不在線程之間共享數據,就可以安全地運行線程。

If an other thread needs to read/write data to your thread class, then this won't be thread safe unless you protect data with some synchronization mechanism (like locks).

如果其他線程需要向線程類讀取/寫入數據,那么這將不會是線程安全的,除非您使用一些同步機制(如鎖)保護數據。

#5


0  

To elaborate on DanM's answer, conceivably this could happen:

為了詳細說明DanM的答案,可以想象這可能發生:

  1. Thread 1: t.skip()
  2. 線程1:t.skip()
  3. Thread 2: if self.doSkip: print 'skipped'
  4. 線程2:如果自我。doSkip:打印“跳過”
  5. Thread 1: t.skip()
  6. 線程1:t.skip()
  7. Thread 2: self.doSkip = False
  8. 線程2:自我。doSkip = False
  9. etc.
  10. 等。

In other words, while you might expect to see one "skipped" for every call to t.skip(), this sequence of events would violate that.

換句話說,雖然您可能期望看到一個“跳過”對t.skip()的每一個調用,但是這個事件序列將會違反這個順序。

However, because of your sleep() calls, I think this sequence of events is actually impossible.

然而,由於您的睡眠()調用,我認為這一系列事件實際上是不可能的。

(unless your computer is running really slowly)

(除非你的電腦運行很慢)


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2009/04/17/7213016849783cca0fab027b7843304f.html



 
粤ICP备14056181号  © 2014-2021 ITdaan.com