Como fazer com que os recipientes internos (conjuntos, canais, listas) sejam seguros?

Compreendodesta pergunta que se eu quiser ter umset que é thread-safe Eu tenho que implementar a parte de segurança de thread por conta própria.

Portanto, eu poderia propor:

from threading import Lock

class LockedSet(set):
    """A set where add() and remove() are thread-safe"""

    def __init__(self, *args, **kwargs):
        # Create a lock
        self._lock = Lock()
        # Call the original __init__
        super(LockedSet, self).__init__(*args, **kwargs)

    def add(self, elem):
        self._lock.acquire()
        try:
            super(LockedSet, self).add(elem)
        finally:
            self._lock.release()

    def remove(self, elem):
        self._lock.acquire()
        try:
            super(LockedSet, self).remove(elem)
        finally:
            self._lock.release()

Portanto, é claro que apenas add () e remove () são thread-safe nesta implementação. Os outros métodos não são porque não foram sobrescritos na subclasse.

Agora, o padrão é bastante simples: adquirir bloqueio, chamar método original, liberar bloqueio. Se eu seguir a lógica acima, eu teria que substituir todos os métodos expostos porset essencialmente da mesma maneira, por exemplo:

(pseudo-código)

def <method>(<args>):
    1. acquire lock
    2. try:
    3.     call original method passing <args>
    4. finally:
    5.     release lock

(/pseudo-código)

Isso não é apenas tedioso, mas também propenso a erros. Então, quaisquer idéias / sugestões sobre como abordar isso de uma maneira melhor?

questionAnswers(4)

yourAnswerToTheQuestion