我注意到它經常被建議使用多線程隊列,而不是列表和.pop()
。這是因爲列表不是線程安全的或者其他原因?列表線程安全嗎?
列表線程安全嗎?
回答
列表本身是線程安全的。在CPython中,GIL可以防止對它們的併發訪問,其他實現會爲列表實現注意使用細粒度鎖定或同步數據類型。然而,雖然列表本身不能因嘗試同時訪問而損壞,但列表的數據未受保護。例如:
L[0] += 1
不能保證由一個,如果另一線程做同樣的事情,以實際上增加L [0],因爲+=
不是一個原子操作。 (Python中非常少的操作實際上是原子操作,因爲其中大多數操作都可能導致任意Python代碼被調用。)應該使用隊列,因爲如果您只是使用不受保護的列表,您可能會獲取或刪除錯誤的項目,因爲的競賽條件。
爲了澄清托馬斯的優秀答案中的一點,應該提及append()
是線程安全。
這是因爲沒有擔心數據被讀取將在同一個地方,一旦我們去寫它。 append()
操作不讀取數據,它只將數據寫入列表。
PyList_Append正在從內存中讀取。你的意思是它的讀寫發生在同一個GIL鎖? https://github.com/python/cpython/blob/1cecdbbf1adef9af2ac829c7dbba91352accb1fd/Objects/listobject.c#L303 – amwinter 2014-09-24 13:13:16
@amwinter是的,對'PyList_Append'的整個調用是在一個GIL鎖中完成的。它被賦予一個要追加的對象的引用。在對對象的內容進行評估之後以及對「PyList_Append」的調用完成之前,該對象的內容可能會被更改。但它仍然是同一個對象,並且安全地附加了(如果你執行lst.append(x); ok = lst [-1]是x',那麼'ok'當然可能是False)。 您引用的代碼不會從附加對象中讀取,INCREF除外。它讀取並可能重新分配附加到的列表。 – greggo 2016-05-09 14:24:35
dotancohen的觀點是'L [0] + = x'會在'L'上執行一個'__getitem__',然後在'L'上執行一個'__setitem__' - 如果'L'支持'__iadd__'它會做事在對象接口上有點不同,但是在python解釋器級別上對'L'仍然有兩個獨立的操作(你會在編譯的字節碼中看到它們)。 'append'是在字節碼中的單個方法調用中完成的。 – greggo 2016-05-09 14:33:05
Here's a comprehensive yet non-exhaustive list of examples的list
操作以及它們是否是線程安全的。 希望得到有關obj in a_list
語言構造here的答案。
第一個鏈接似乎已經死亡。 – displayname 2017-04-29 11:27:01
- 1. 列表複製線程安全嗎?
- 2. java線程安全:線程安全嗎?
- 3. VB.NET線程安全列表?
- 4. 將列表傳遞給線程。線程安全嗎?
- 5. Spring mongoTemplate線程安全嗎?
- 6. Lparallel.queue線程安全嗎?
- 7. BoxClient線程安全嗎?
- 8. EventHubClient.SendBatchAsync - 線程安全嗎?
- 9. .NET:JsonMediaTypeFormatter線程安全嗎?
- 10. multiset equal_range線程安全嗎?
- 11. pip線程安全嗎?
- 12. com.google.cloud.datastore.Datastore線程安全嗎?
- 13. WNetGetResourceInformation線程安全嗎?
- 14. qsort線程安全嗎?
- 15. work_queue線程安全嗎?
- 16. .NET DateTime線程安全嗎
- 17. DynamoDBContext線程安全嗎?
- 18. 在Python線程安全嗎?
- 19. java.lang.reflect.Method線程安全嗎?
- 20. HttpContext.Current.Cache線程安全嗎?
- 21. UIFont線程安全嗎?
- 22. C#+ =線程安全嗎?
- 23. Go bytes.Buffer線程安全嗎?
- 24. SynchronizationContext.Post()線程安全嗎?
- 25. Guava Table線程安全嗎?
- 26. EPiServer線程安全嗎?
- 27. 是java.sql.Connection線程安全嗎?
- 28. 是CreateChildContainer()線程安全嗎?
- 29. 是Thread.getStackTrace()線程安全嗎?
- 30. Windows'rand_s線程安全嗎?
Deque也是線程安全的嗎?這似乎更適合我的使用。 – lemiant 2011-06-12 00:06:20
所有Python對象都具有相同的線程安全性 - 它們本身不會損壞,但它們的數據可能會損壞。 collections.deque是Queue.Queue對象的後面。如果你從兩個線程訪問東西,你應該使用Queue.Queue對象。真。 – 2011-06-12 00:09:31
lemiant,deque是線程安全的。從Fluent Python的第2章:「類collections.deque是一個線程安全的雙端隊列,設計用於從兩端快速插入和刪除。[...] append和popleft操作是原子操作,因此deque是安全的在多線程應用程序中用作LIFO隊列 ,而不需要使用鎖。「 – 2018-01-10 00:12:37