Многопоточная сортированная коллекция - PullRequest
4 голосов
/ 25 октября 2011

Есть ли в Python реализация поточно-отсортированной коллекции?
Документы Python ссылка SortedCollection но я не уверен, что она поточно-ориентирована (не так ли)
Если такой реализации нет - как бы вы ее реализовали?

Ответы [ 5 ]

4 голосов
/ 25 октября 2011

Просматривая код, он не выглядит потокобезопасным. Чтобы использовать его из нескольких потоков, код приложения, который обращается к нему, должен быть защищен семафорными замками.

Если вы хотите сделать поток класса 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)

Возможно, что другой поток может вставить элемент между этими двумя операторами. Вам нужно будет охранять код вашего приложения. Если вы добавите это в код своего приложения, вам не нужно будет изменять SortedCollection для обеспечения безопасности потоков.

semaphore2.acquire()

try:
    slist.insert(1)
    slist.insert(2)
finally:
    semaphore2.release()
1 голос
/ 25 октября 2011

Вы можете использовать модуль 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)
1 голос
/ 25 октября 2011

Класс collection.OrderedDict не является потокобезопасным для обновлений.Вы можете выполнять одновременное чтение, но для записи необходимы блокировки.Для примера того, как использовать блокировки с OrderedDict , см. Источник для functools.lru_cache () .

1 голос
/ 25 октября 2011

Python отличается от Java: если класс не определил свое многопоточное поведение в документах, можно с уверенностью предположить, что он не поточнобезопасен.

Python написан не с учетом потоков. Даже сегодня многопоточность действительно относится ко второму классу, так как во все времена активен только один поток (что не предотвращает большинство проблем с передачей данных). Это называется Global Interpreter Lock (GIL).

Если класс или структура данных не созданы для параллелизма, вы должны защитить доступ к ним с помощью внешней блокировки

0 голосов
/ 26 сентября 2014

Атомарные операции всегда являются поточно-ориентированными в python.Синхронизировать нужно только в том случае, если операции не являются атомарными.GIL допускает только одну атомарную операцию за раз, независимо от количества потоков.Мультиобработка в python - это другое дело.

...