試圖澄清我對執行緒的理解。
據我了解,當 GIL 不是手動釋放時(例如 time.sleep),作業系統會隨機將其分配給執行緒,對嗎?如果是這樣,為什么這里從來沒有出現過競爭條件?我已經多次重新運行代碼并且記錄的結束值(最后一行)始終是5.
我原以為在某些運行中,某些執行緒會local_copy在另一個執行緒更新之前獲得 a self.value,從而導致競爭條件。此外,這是否意味著執行緒同步運行,因為每個執行緒都在等待前一個執行緒寫入self.value = local_copy?
我的想法是作業系統有一些識別共享屬性的讀寫程序的程序,因此以防止任何競爭條件發生的方式將 GIL 分配給執行緒。
class FakeDatabase:
def __init__(self):
self.value = 0
def update(self, name):
logging.info("Thread %s: starting update", name)
local_copy = self.value
local_copy = 1
self.value = local_copy
logging.info("Thread %s: finishing update", name)
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
database = FakeDatabase()
with futures.ThreadPoolExecutor() as executor:
for i in range(5):
executor.submit(database.update, i)
logging.info(f'Ending value is {database.value}')
uj5u.com熱心網友回復:
每個執行緒只做一個增量,增量是一個相對較短的部分,因此增量很可能不會重疊。如果我讓每個執行緒增加一百萬次
for _ in range(10**6):
local_copy = self.value
local_copy = 1
self.value = local_copy
然后我確實看到它發生了(在線嘗試!):
INFO:root:Thread 0: starting update
INFO:root:Thread 1: starting update
INFO:root:Thread 2: starting update
INFO:root:Thread 3: starting update
INFO:root:Thread 4: starting update
INFO:root:Thread 4: finishing update
INFO:root:Thread 0: finishing update
INFO:root:Thread 3: finishing update
INFO:root:Thread 2: finishing update
INFO:root:Thread 1: finishing update
INFO:root:Ending value is 1745053
uj5u.com熱心網友回復:
Python 的執行緒與 CPU 系結任務(如上面的示例案例)在后臺以同步方式有效地運行,Python 中執行緒的真正好處在于 I/O 系結任務,例如等待來自網路或磁盤的某些內容。
雖然很老,但這是一個很好的討論
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/488418.html
下一篇:在Haskell中顯示結果
