6

varsayalım ben, statik kütüphanede bir tekil sınıf S bu diğer dinamik kütüphaneleri D1 D2 D3 ile bağlantılı olabilir varSingleton sınıf

Sınıf S ayrı olacak anladığım kadarıyla Yani

her D1, D2 ve D3 ve (küresel) gibi bir tekil

birden fazla kopya sınıf S önlemek için herhangi bir yolu var mı olmasa bile bu doğru olurdu içinde örnek? Tekil S'yi başka bir Dinamik kitaplığa koyamıyorum.

    Executable 
       / | \ \ 
       D1 D2 D3 D4 
       | | | 
       S S S 

DÜZENLEME: tekil S ayrı ayrı ... D1 D2 D3 ile bağlantıları ayrı statik kütüphanede.

Ben Bu örnek makefile (tarafından .dll değiştirin şeyleri kontrol etmek için basit bir test durumu yaptı:
tekil yığın tahsis edilir, ancak işaretçi

static s::instance() 
{ 
    static smart_ptr<S> ptr = NULL; 
    if(ptr == NULL) ptr = new S; 
    return ptr; 
} 

Edit2 statiktir. yani) bir şeyleri kontrol etmek için yaptım, Ubuntu ve Cygwin üzerinde kontrol ettim, hem g ++ derleyiciler hem de davranış farklıydı. cygwin 2 farklı nesneler yarattı fakat ancak ubuntu 1 nesneleri

all: dynamic1 dynamic2 main 

static: static.cpp 
    g++ -c -fPIC static.cpp -o obj/static.o 
    ar rvs lib/static.a obj/static.o 

dynamic1: static dynamic1.cpp 
    g++ -fPIC -shared dynamic1.cpp lib/static.a -o lib/libdynamic1.dll 

dynamic2: static dynamic2.cpp 
    g++ -fPIC -shared dynamic2.cpp lib/static.a -o lib/libdynamic2.dll 

main: dynamic1 dynamic2 main.cpp 
    g++ --std=c++11 main.cpp -ldynamic1 -ldynamic2 -o lib/main -L./lib 
+0

Amacınız nedir? Paylaşılan kaynaklara erişimi kontrol etmek istiyorsanız, örneğin [destek] kullanarak (http://www.boost.org/doc/libs/1_61_0/doc/html/interprocess/synchronization_mechanisms.html) –

+0

Hayır arası işlemler arası eşitleme kullanabilirsiniz. Bu işlemler arasındaki paylaşılan bellekle ilgili değildir. – tejas

+0

@tejas: Windows'ta neden bir DLL yapamıyorsunuz? –

cevap

2

singletone için uygulama iki olgu vardır yarattı.

1 bir işaretçi olarak, tek bir örneği, getInstance dinamik bu durumda yığın bellek tahsis edecektir. , tek örnek statik üyesi ve ayırma olur hafıza vardır.

bulunan statik hafıza olduğu, aşağıdaki bağlantı anlatılmaktadır: Yukarıdaki uygulama herhangi birinde Where are static variables stored (in C/C++)?

: D1, D2, D3 ve D4 (çeşitli iplikler kullanılan gibi) aynı uygulama ve dolayısıyla aynı işlem ise, o zaman aynı singletonu paylaşırlar. Eğer D1, D2, D3 ve D4 farklı işlemlere aitse, yani kendi bellek alanlarına sahiptirler ve böylece aynı tekil paylaşmazlar. Dinamik bağlayıcı kırık değilse

+0

örneğine erişen çok sayıda iş parçacığınız varsa, bu davranışın farklı olduğunu fark ettiğim gibi yanıt olarak algıladım – tejas

+0

, Windows'un bu şekilde çalıştığı muhteşem! –

+0

Bu cevabı MSVC kapsamında yanlış buldum. Statik kitaplık olarak boost_serialization kullanımı, statik kitaplığı bağlayan modül başına bir kez arka uç tekillerini (örneğin, tip bilgisi için) bir kez başlatır. Bu sırayla bu arka ucun tüm amacı (kaydedilmemiş sınıf istisnası) bozuldu –

5

, herhangi bir sorun olmamalıdır. Her dinamik kitaplık aslında statik kitaplık S'den nesne dosyalarını içeriyor olsa bile, dinamik yükleyici, aynı sembolle aynı olduklarını ve tüm uygulama boyunca tutarlı olarak aynı adresleri kullandıklarını belirlemek için yeterince akıllı olmalıdır. Kısacası

, sistem kırık değilse burada


Düzenlemenizle Başına sorun yoktur, gerçek bir dinamik yükleyici vardır, yukarıdaki güzel bir yer olması gerektiği şekilde olduğunu teyit dünya ve Unix benzeri sistemlerde olduğu gibi. Ubuntu'da çalıştığını söylüyorsun ve teyit edip FreeBSD'de aynı şekilde çalıştığını söyleyebilirim.

Fakat Windows üzerinde

, maalesef farklıdır. ld.so gibi gerçek bir dinamik yükleyiciniz yok, ancak yalnızca dışa aktarılan işlevlerin adreslerini veya DLL dosyasındaki verileri gerektirir. Bu birleştirmek için hiçbir küresel bağlama aşaması olmadığından her onu kod kendi kopyasını içeren ve kullanacağı çünkü bir sonucu olarak, her DLL, tekiz kendi kopyasını kullanacaktır.

Daha da kötüsü, basit bir çözüm bulacağımı hayal edememektir: statik bağlantı ve dinamik bağlantı farklı davranışı tam olarak durdurur. Bu, Windows üzerinde dinamik bağlantı kullandığınız anda, tek bir satır veya en az iki farklı DLL'den erişilebilen herhangi bir paylaşılan veri, bir DLL anlamında tek bir yerde bulunmalıdır.

TL/DR: Sisteminizde gerçek bir dinamik yükleyici (Unix gibi var) varsa, statik veya dinamik bağlantı hakkında endişelenmenize gerek kalmaz, yükleyici (ld.so) bununla ilgilenir. Windows'da dinamik bir yükleyiciye sahip olmayan ancak çalışma zamanı LoadLibrary API çağrısı olan herhangi bir paylaşılan verinin tek bir modülde bulunması gerekir.

+0

Ben – tejas

+0

@tejas Soru güncellendi ettik ve ben cevabı güncelledim ... –