2015-12-20 44 views
5

C++ 11, <functional> iş parçacığı güvenli alanında bildirilen karma işlev sınıfı nesneleridir? Ör., Bu işlevi birden çok ileti dizisinden çağırmak güvenli midir? tek bir küresel nesne std::hash<std::string> str_hash_global; varsaC++ 11 std :: hash function nesne sınıfları thread safety

size_t hash1(const std::string& s) { 
    std::hash<std::string> str_hash; 
    return str_hash(s); 
} 

ya, o zaman birden çok iş parçacığı bu ikinci işlevi çağırmak için güvenli?

size_t hash2(const std::string& s) { 
    return str_hash_global(s); 
} 
+0

Diğer hususlar bir kenara, karma hesaplanırken dizenin kendisinin aynı anda değiştirilmediğinden emin olun. –

cevap

6

standart kütüphane vaat olduğunu standart bir kütüphane nesne üzerinde const ulaşım kolaylığı üye fonksiyonları sadece çağrı, standart kütüphane kodu (Bkz [res.on.data.races veri yarışı neden olmuyorsa ]).

standart şablon std::hash, hem de tüm izin verilen uzmanlık yanı sıra Hash gereksinimleri karşılayan herhangi bir kullanıcı tarafından sağlanan funktor ([hash.requirements]) bir const ulaşım kolaylığı arama operatörü sahip olması gerekir şartlarına göre, ve böylece kütüphane tarafından sağlanan std::hash uzmanlıklarının kullanılması bir yarışa neden olmamalıdır. Ayrıca, [namespace.std] nedeniyle, program tarafından sağlanan uzmanlıkların aynı gereksinimleri karşılaması gerekir.

Son olarak, genellikle yinelemeli const çağrılarına hitap ederek yarış serbestlik garantileri kullanacağı hayal: Birden parçacığı aynı anda bir harita değerleri aramak, bunlar yukarıda kütüphane çağırmak için haritanın const arayüzü kullanmak zorunda kuralı, ancak daha sonra harita sadece sabit bir (veya özel bir kopya) sabit değerini kullanır ve böylece sadece ırksız karma hesaplamalar yapabilir. Küfürlü bir yerleşik olmayan çağrı işlecinin var olup olmadığı bu noktada immettir.

+0

'gereksinimleri nedeniyle yapıda kalifiye bir çağrı operatörüne sahip olmalıdır 'standardın hangi kısmı gerektiriyor? Bunu söyleyen bir şey arıyordum ve bulamadım. "Geri döndürülen değer, programın süresi boyunca sadece k argümanına bağlı olacaktır", fakat bu doğrudan "operatör()" const-qual "olmalıdır." –

+0

@IgorTandetnik: " h '(muhtemelen' const ') değeridir. –

+1

Ah, evet, öyle. "h", kesin olması için bir tür (muhtemelen const) "H" "değeridir. Ben hala, operatör() 'in, bir const ve bir non-const'ın iki aşırı yüklenmesini sağlayan bir sınıfı kesinlikle engellemediğini varsayalım (bunun neden herkesin bunu yapmak isteyeceği net değil). –

2

Aynı "iş güvenliği" kuralları, tüm std :: lib türlerinde olduğu gibi burada da geçerlidir.

İlk sürüm, iş parçacıkları arasında paylaşılan hiçbir değişken olmadığından, iş parçacığı için güvenli olduğu garanti edilir.

İkincisi, aradığında operator()const ise herhangi bir veri yarışması olmaması garantilidir. Uygulamanın (zorunlu) const birine ek olarak hash<T>::operator() (potansiyel olarak iplik olmayan güvenli) sabit olmayan aşırı yüklenme sağlayıp sağlamadığı belirtilmemiş. global_str_hash'unuz const ise veya kullanmadan önce const'e gönderirseniz, operator() yapısının kullanılacağını garanti edersiniz.

İkinci sürümü yapmak için bir neden yok, sadece aptalca, ama pratikte güvenli olmalı, çünkü standart kütüphane uygulamasının hash::operator() no'lu standart olmayan bir aşırı yüklenme sağlaması muhtemeldir, sadece bir aşırı yüklenme sağlayacaktır iplik güvenli olmalıdır.

İlgili konular