Python'un sözlüğünde Konu Güvenliği


107

Sözlüğü olan bir sınıfım var

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

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

Ve yöntemi çağıran 4 iş parçacığı (her restoran için bir tane) çalıştırıyorum OrderBook.addOrder. İşte her iş parçacığı tarafından çalıştırılan işlev:

def addOrders(restaurant_name):

    #creates orders
    ...

    OrderBook.addOrder(restaurant_name, orders)

Bu güvenli mi, yoksa aramadan önce kilit kullanmam gerekiyor addOrdermu?


2
her iş parçacığı zaten farklı bir anahtara yazdığında nasıl bir sorun olabilir.
Jochen Ritzel

65
@Jochen: Kuralların nasıl uygulandığına bağlı olarak, birçok şey yanlış gidebilir. Bu çok makul bir soru.
Ned Batchelder

Yanıtlar:


97

Python'un yerleşik yapıları, tekli işlemler için iş parçacığı açısından güvenlidir, ancak bazen bir ifadenin gerçekten birden çok işlem haline geldiğini görmek zor olabilir.

Kodunuz güvenli olmalıdır. Unutmayın: Buradaki bir kilit neredeyse hiçbir ek yük getirmez ve size içinizin rahat olmasını sağlar.

http://effbot.org/pyfaq/what-kinds-of-global-value-mutation-are-thread-safe.htm'de daha fazla ayrıntı var.


6
İşte effbot.org kilit uygulanmasına
ocaklar

1
Get -add-set gibi bileşik işlemlere karşılık tek işlem dikkate alınmalıdır .
andy

5
sorun şu ki, bu dikteyi sık sık okuduğumda / yazdığımda, iç huzurunun bana çok pahalıya mal olacağı.
Shihab Shahriar Khan

2
"Buradaki bir kilit neredeyse hiçbir ek yük getirmez": bu neden?
en fazla

32

Evet, yerleşik türler doğası gereği iş parçacığı açısından güvenlidir: http://docs.python.org/glossary.html#term-global-interpreter-lock

Bu, nesne modelini (dikte gibi kritik yerleşik türler dahil ) eşzamanlı erişime karşı örtük olarak güvenli hale getirerek CPython uygulamasını basitleştirir .


25
Bu Python'un bir özelliği değil, cpython'un bir özelliği .
phihag

8
Doğru, ama anladığım kadarıyla, Jython ve IronPython'daki yerleşikler, GIL kullanılmasa bile iş parçacığı açısından güvenlidir (ve eğer ortaya çıkarsa, GIL'i de ortadan kaldırmayı önerir). Kullandığı tercümanı belirtmediği için CPython'da kastettiğini varsaydım.

1

9

Google'ın stil kılavuzu, atomikliği dikte etmekten kaçınmanızı tavsiye ediyor

Aşağıdaki sayfada daha ayrıntılı olarak açıklanmıştır: Python değişken ataması atomik mi?

Yerleşik türlerin atomikliğine güvenmeyin.

İken Python yerleşik sözlük gibi veri türleri onlar atom değildir köşe durumlar vardır, atomik işlemleri var görünüyor (örn eğer __hash__veya __eq__Python yöntemleri olarak uygulanır) ve bunların bölünmezlik üzerine itibar edilmemelidir. Atomik değişken atamasına da güvenmemelisiniz (çünkü bu sırayla sözlüklere bağlıdır).

İş Queueparçacıkları arasında veri iletişimi için tercih edilen yol olarak modülün Kuyruk veri türünü kullanın . Aksi takdirde, diş çekme modülünü ve onun kilitleme ilkelerini kullanın. Daha threading.Conditiondüşük seviyeli kilitler kullanmak yerine kullanabilmek için koşul değişkenlerinin doğru kullanımı hakkında bilgi edinin .

Ve buna katılıyorum: CPython'da zaten GIL var, bu yüzden bir Lock kullanmanın performans etkisi ihmal edilebilir olacak. Bu CPython uygulama ayrıntıları bir gün değiştiğinde, karmaşık bir kod tabanında hata aramak için harcanan saatler çok daha maliyetli olacaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.