Atom vektörünün başlatılması


12

Düşünmek:

void foo() {
  std::vector<std::atomic<int>> foo(10);
  ...
}

Foo'nun içeriği artık geçerli mi? Yoksa açık bir şekilde döngü yapmam ve bunları başlatmam gerekir mi? Godbolt üzerinde kontrol ettik ve iyi görünüyor, ancak standart bu noktada çok karışık gibi görünüyor.

Std :: vector yapıcı o ekler diyor varsayılan eklenen örneklerini std::atomic<int>vardır başlatıldı değer yerleşimi yoluyla new.

Değer başlatmanın bu etkisinin geçerli olduğunu düşünüyorum:

2) T, kullanıcı tarafından sağlanan veya silinmeyen varsayılan bir kurucuya sahip bir sınıf türüyse (yani, örtülü olarak tanımlanmış veya varsayılan bir varsayılan kurucuya sahip bir sınıf olabilir), nesne sıfırla başlatılır ve sonra önemsiz olmayan bir varsayılan kurucu varsa varsayılan olarak başlatılmış;

Bana öyle geliyor ki atomlar sıfır başlatıldı. Yani soru şu ki, bir std::atomic<int>sonucun sıfır başlatılması geçerli bir nesnede mi?

Cevabın "pratikte evet ama gerçekten tanımlanmamış" olduğunu tahmin edeceğim.

Not: Bu yanıt sıfır olarak başlatıldığını kabul eder, ancak bunun nesnenin geçerli olduğu anlamına gelip gelmediğini söylemez.

Yanıtlar:


7

Endişelenme konusunda haklısın. Standart atomics göre ancak bunlar çağırdın, varsayılan kurucuyu sahip değil gibi başlatıldı. Bunun nedeni, varsayılan kurucunun atomik değeri başlatmamasıdır:

Varsayılan olarak başlatılmış std::atomic<T>bir Tnesne içermez ve tek geçerli kullanımları std :: atomic_init tarafından imha ve başlatmadır

Bu biraz normal dil kurallarını ihlal ediyor ve bazı uygulamalar yine de başlıyor (not ettiğiniz gibi).

Bununla birlikte, standartlara göre doğru şekilde başlatıldıklarından% 100 emin olmak için ekstra adım atmanızı tavsiye ederim - sonuçta hataların izlenmesi son derece zor olabileceği eşzamanlılık ile uğraşıyorsunuz.

Sarıcı kullanmak da dahil olmak üzere sorunu atlatmanın birçok yolu vardır:

struct int_atomic {
   std::atomic<int> atomic_{0};//use 'initializing' constructor
};

Ya da aslında kullanın atomic_init. Zaten sorudaki kod etrafında senkronize etmek zorundasınız
Orbit'te Lightness Races

O kadar varsayılan yapıcı önemsiz değildir (söz konusu alıntı başına) neyse denen
Orbit Açıklık Races

Ayrıca mümkün olan @LightnessRaceswithMonica, sadece sarıcıyı vurgulamak istiyorum
Darune

@LightnessRaceswithMonica, bazı derleyiciler bu istisnayı uygulamasa da normal dil kurallarına bir istisnadır. StoreTeller yanıtının% 100 doğru olduğundan emin değilim.
Darune

2

Varsayılan kurucu çağrılmış olsa bile (önemsiz olduğu için değil) gerçekten hiçbir şey yapmaz .

Sıfır başlatma işleminin, geçerli bir atom ürettiği açıktır; bu sadece tesadüfen tüm üyeleri sıfırdan başlatarak geçerli bir atom oluşturulursa işe yarar .

Ve atomlar kopyalanamadığından, vektör yapıcısında bir başlatma değeri sağlayamazsınız.

Şimdi kabın ve std::atomic_inither öğenin üzerinde döngü yapmalısınız . Bunu kilitlemeniz gerekiyorsa, bu iyi çünkü aynı nedenden dolayı vektörün oluşturulmasını senkronize ediyorsunuz.


@darune Ben bir tür senkronizasyon olduğunu düşünüyorum;)
Orbit'te Hafiflik Yarışları
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.