Python 사전의 스레드 안전성


105

사전이있는 수업이 있습니다.

class OrderBook:
    orders = {'Restaurant1': None,
              'Restaurant2': None,
              'Restaurant3': None,
              'Restaurant4': None}

    @staticmethod
    def addOrder(restaurant_name, orders):
        OrderBook.orders[restaurant_name] = orders

그리고 메서드를 호출하는 4 개의 스레드 (각 레스토랑에 대해 하나씩)를 실행하고 있습니다 OrderBook.addOrder. 다음은 각 스레드에서 실행되는 함수입니다.

def addOrders(restaurant_name):

    #creates orders
    ...

    OrderBook.addOrder(restaurant_name, orders)

안전합니까, 아니면 전화하기 전에 자물쇠를 사용해야 addOrder합니까?


2
어쨌든 각 스레드가 다른 키에 쓸 때 어떻게 문제가 발생할 수 있습니까?
Jochen Ritzel 2011-08-05

63
@Jochen : 딕셔너리가 어떻게 구현되는지에 따라 많은 것이 잘못 될 수 있습니다. 이것은 매우 합리적인 질문입니다.
Ned Batchelder 2011-08-05

답변:


95

Python의 내장 구조는 단일 작업에 대해 스레드로부터 안전하지만 문이 실제로 여러 작업이되는 위치를 확인하기 어려울 수 있습니다.

코드는 안전해야합니다. 여기에 잠금 장치를 사용하면 오버 헤드가 거의 추가되지 않으며 안심할 수 있습니다.

http://effbot.org/pyfaq/what-kinds-of-global-value-mutation-are-thread-safe.htm 에 자세한 내용이 있습니다.


6
다음은 effbot.org 에서 잠금
hobs

1
단일 작업과 복합 작업 (예 : get-add-set)을 고려해야 합니다 .
andy

5
문제는 내가 그 딕셔너리를 자주 읽고 쓸 때 마음의 평화가 나에게 많은 비용을 들이게 될 것이라는 것입니다.
Shihab Shahriar Khan

2
"여기에 자물쇠가 있으면 오버 헤드가 거의 추가되지 않습니다."
최대

32

예, 내장 유형은 본질적으로 스레드로부터 안전합니다. http://docs.python.org/glossary.html#term-global-interpreter-lock

이는 동시 액세스에 대해 암시 적으로 안전한 객체 모델 ( dict와 같은 중요한 내장 유형 포함) 을 만들어 CPython 구현을 단순화합니다 .


25
이것은 Python의 기능이 아니라 cpython 의 기능입니다 .
phihag 2011-08-05

8
사실이지만 내가 이해하는 바와 같이 Jython과 IronPython에 내장 된 내장 기능은 GIL을 사용하지 않아도 스레드로부터 안전합니다 (그리고 이것이 나타날 경우, GIL도 제거 할 것을 제안합니다). 나는 그가 사용하는 통역사를 지정하지 않았기 때문에 그가 CPython에서 의미하는 것이라고 생각했습니다.

1
자이 썬의 경우 수정 : jython.org/jythonbook/en/1.0/...
예브게니 Sergeev

9

Google의 스타일 가이드는 dict 원자성에 의존하지 말라고 조언합니다.

더 자세히 설명 : 파이썬 변수 할당은 원자 적입니까?

기본 제공 유형의 원자성에 의존하지 마십시오.

반면 파이썬에 내장 된 사전과 같은 데이터 유형들은 원자 수없는 코너 케이스가, 원자 작업을 가지고있는 것 같습니다 (예를 들어, 경우 __hash__또는 __eq__파이썬 방법으로 구현)과 자성이에 의존해서는 안됩니다. 원자 변수 할당에 의존해서는 안됩니다 (이는 사전에 따라 달라지기 때문입니다).

Queue스레드간에 데이터를 통신하는 기본 방법으로 모듈의 큐 데이터 유형을 사용하십시오 . 그렇지 않으면 threading 모듈과 잠금 프리미티브를 사용하십시오. threading.Condition하위 수준 잠금을 사용 하는 대신 사용할 수 있도록 조건 변수의 적절한 사용에 대해 알아 봅니다 .

그리고 저는 이것에 동의합니다. CPython에는 이미 GIL이 있으므로 Lock 사용으로 인한 성능 저하는 무시할 수있을 것입니다. CPython 구현 세부 사항이 언젠가 변경되면 복잡한 코드베이스에서 버그를 찾는 데 소요되는 시간이 훨씬 더 비쌉니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.