SORU
22 Mayıs 2011, Pazar


Çift-İşaretli C 11 Kilit Singleton

Aşağıdaki singleton uygulaması veri-yarış ücretsiz mi?

static std::atomic<Tp *> m_instance;
...

static Tp &
instance()
{
    if (!m_instance.load(std::memory_order_relaxed))
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        if (!m_instance.load(std::memory_order_acquire))
        {
            Tp * i = new Tp;
            m_instance.store(i, std::memory_order_release);    
        }    
    }

    return * m_instance.load(std::memory_order_relaxed);
}

Yükleme işlemi std::memory_model_acquire gereksiz mi? Daha fazla std::memory_order_relaxed onları geçerek hem yük ve depo işlemleri rahatlamak mümkün mü? Bu durumda, elde/release semantik std::mutex yeterince garanti onun doğruluğu, bir veya daha fazla std::atomic_thread_fence(std::memory_order_release) de gerekli sağlamak için yazar için bellek kurucu meydana gelmeden rahat mağaza? Çit kullanımı memory_order_release mağaza var eşdeğer mi?

EDİTJohn cevap için teşekkürler, veri-yarış ücretsiz olması gereken aşağıdaki uygulama ile geldim. İç yük olmayan atom hiç de olsa, bu performansını etkilemez, o rahat bir yük ayrılmaya karar verdim. Karşılaştırıldığında, her zaman kazanmak bellek sırası ile dış yük, thread_local makine bir büyüklük sırası hakkında örneğine erişim performansını artırır.

static Tp &
instance()
{
    static thread_local Tp *instance;

    if (!instance && 
        !(instance = m_instance.load(std::memory_order_acquire)))
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        if (!(instance = m_instance.load(std::memory_order_relaxed)))
        {
            instance = new Tp; 
            m_instance.store(instance, std::memory_order_release);    
        }    
    }
    return *instance;
}

CEVAP
23 Mayıs 2011, PAZARTESİ


Bu çok güzel bir soru bence ve John Calsbeek doğru cevabı vardır.

Ancak, sadece tembel bir singleton en iyisi açık olmak klasik Meyers tekil kullanılarak uygulanan. C 11 doğru semantiği kabul etti.

§ 6.7.4

... Eğer kontrol girer değişken başlatılırken Bildirgesi aynı anda, eşzamanlı yürütme bekleyim başlatma tamamlanması. ...

Meyer'ın singleton derleyici agresif eşzamanlı kodu optimize tercih ediliyor. Derleyici eğer std::mutex semantiği korumak için olsaydı daha kısıtlı olurdu. Ayrıca, Meyer singleton2 satırve yanlış almak neredeyse imkansız.

İşte Meyer'in singleton klasik bir örnek. C 03 basit, şık, ve kırık. Ama c 11 basit, zarif ve güçlü.

class Foo
{
public:
   static Foo& instance( void )
   {
      static Foo s_instance;
      return s_instance;
   }
};

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Jason Rosolowski

    Jason Rosolo

    25 EKİM 2006
  • Kyler Briskey

    Kyler Briske

    20 ŞUBAT 2011
  • nigahiga

    nigahiga

    21 Temmuz 2006