Pythonでスレッドセーフソートコレクションの実装がありますか?
Python's docs参照SortedCollectionしかし、スレッドセーフであればわかりません(それは?)
このような実装がない場合、どのように実装しますか?スレッドセーフなソートコレクション
答えて
PythonはJavaとは異なります。クラスがドキュメント内でスレッド動作を指定していない場合は、スレッドセーフではないと見なすのが安全です。
Pythonはスレッディングを念頭に置いて書かれていません。今日でも、マルチスレッドは実際には2つのクラスの市民であり、常に1つのスレッドしかアクティブではありません(ほとんどのデータ競合の問題を防ぎません)。これは、グローバルインタープリターロック(GIL)と呼ばれます。
クラスまたはデータ構造は、同時実行のために構築されていない場合は、コードを見ると、スレッドセーフであるとは思われないexternal lock
これは実際にJavaと全く違うものではありません。 Javaでは、スレッディングに関して何も言及されていない場合、スレッドセーフではないと想定するのは安全です。 Pythonとは逆に、スレッドセーフなコレクションを手に入れますが、悲しいことに、Pythonの点では/ – Voo
によって、それへのアクセスを保護する必要があります。それを複数のスレッドから使用するには、それにアクセスするアプリケーションコードをセマフォーロックで保護する必要があります。
SortedCollectionクラスをスレッドセーフにしたい場合は、デコレータ関数を記述することができます。
それは次のようになります。
のSortedCollection:スレッドセーフデータ構造は、アプリケーションコードのスレッドを作ることを考えてのミスをしないでください
def __init__(self):
self.mysemaphore = threading.Semaphore()
def guard(func):
def guarded(*args, **kwds):
self.mysemaphore.acquire()
try:
return func(*args, **kwds)
finally:
self.mysemaphore.release()
return guarded
# edit the class, applying the decorator to its methods.
@guard
def unsafeFunc(self, a, b, c):
''' do work here'''
EDIT
安全。 SortedCollectionで複数の操作を実行する場合、それらの操作はすべてロックによって保護される必要があります。 SortedCollectionは、スレッドセーフであっても
は、次のコードはないであろう。
slist.insert(1)
slist.insert(2)
別のスレッドがそれらの2文の間にアイテムを挿入することが可能です。アプリケーションコード内でガードする必要があります。これをアプリケーションコードに追加すると、SortedCollectionをスレッドセーフに変更する必要はありません。
semaphore2.acquire()
try:
slist.insert(1)
slist.insert(2)
finally:
semaphore2.release()
collections.OrderedDictクラスは、更新のためにスレッドセーフではありません。並行読み取りは可能ですが、書き込みにはロックが必要です。 のOrderedDictでロックを使用する方法の例については、functools.lru_cache()のソースを参照してください。
heapqモジュールを使用すると、並べ替えられたリストを維持できます。 GILの力により、Cエクステンションへのすべての呼び出しはアトミック(拡張が明示的にロックを解除しない限り、CPythonで)であるため、heappush
とフレンドはスレッドセーフです。
from heapq import heappush, heappop
class Heap:
def __init__(self):
self._heap = []
def push(self, x):
heappush(self._heap, x)
def pop(self):
return heappop(self.heap)
... 'heapq'はCの拡張子ではありません! 'heapq'は純粋なpythonで実装されています。 [コード](http://hg.python.org/cpython/file/2.7/Lib/heapq.py)を参照してください。クイックルックから、 'heapq'はスレッドセーフではありません。 – Russ
また、 'heapq'関数自体はスレッドセーフではありませんが、[Queue](http://docs.python.org/library/queue.html)モジュールの[PriorityQueue](http ://docs.python.org/library/queue.html#Queue.PriorityQueue)はスレッドセーフであり、 'heapq'を内部的に使用します。 – Russ
アトミック操作は、常にPythonではスレッドセーフです。操作がアトミックでない場合は、同期する必要があります。 GILは、スレッドの数に関係なく、一度に1つのアトミック操作しか実行できません。 Pythonでのマルチプロセッシングは別の問題です。
- 1. 複数の属性を持つMagentoソートコレクション
- 2. ソートコレクションが期待どおりに機能しない
- 3. mvvmライトで観測可能なソートコレクションを取得する
- 4. PHPスレッドセーフでWindows用でないスレッドセーフ
- 5. スレッドセーフなキュー
- 6. スレッドセーフなC++スタック
- 7. C#:スレッドセーフなイベント
- 8. スレッドセーフなログ
- 9. スレッドセーフな処理
- 10. スレッドセーフなLparallel.queue?
- 11. スレッドセーフなインスタンスフィールド
- 12. スレッドセーフなジェネリックarraylist?
- 13. スレッドセーフな乱数
- 14. スレッドセーフなpthreadミューテックスロックラッパー
- 15. C++スレッドセーフなブラケットオペレータプロキシ
- 16. スレッドセーフなリファクタリング
- 17. スレッドセーフなnsdictionary
- 18. スレッドセーフなOutputStreamWriter
- 19. スレッドセーフな設定
- 20. スレッドセーフな実装
- 21. スレッドセーフなメモ化
- 22. スレッドセーフなインクリメントC#
- 23. スレッドセーフなForm.Show
- 24. JPAのスレッドセーフなエンティティ
- 25. スレッドセーフな同期ブロック
- 26. スレッドセーフなlibapache2-mod-php5
- 27. スレッドセーフなクラスとアクセッサ
- 28. mock.call_countのスレッドセーフなバージョン
- 29. スレッドセーフなバッファ配列
- 30. AsyncTasksとスレッドセーフなデータオブジェクト?
実際に私は、Pythonにそのようなクラスが組み込まれていない理由は実際にはわかりません。 – Jonathan