MSVC 7.1 STL - Threadsafe?



  • Hi,

    1. OK, danke für's Verschieben.
    2. Warum nicht? Dann greift ja immer nur ein Thread gleichzeitig auf die Instanz zu...

    ChrisM



  • Hallo,
    erstens wäre es *extrem* ineffizient, wenn jeder Aufruf gelockt werden würde (wozu eine Mutex locken, wenn z.B. nur ein Thread auf einen Container zugreift?). Zweitens kann ein locking auf Operationsebene nichts gegen Abhängigkeiten die sich über mehrere Aufrufe erstrecken tun.
    Simples Beispiel:

    if (!cont.empty())
    {
    T o = cont.top();
    cont.pop();
    }
    

    Diesen Code kannst du nicht ohne Locking auf Anwendungsebene MT-sicher machen. Prinzipiell könnte ein anderer Thread nach jeder Op den Container verändern.



  • Hi,

    stimmt, du hast recht.

    Dann würde es aber ja reichen, für jeden Container auch einen Mutex zu instantiieren und den dann immer von Hand zu locken (darf man dann halt nie vergessen...).

    ChrisM



  • ChrisM schrieb:

    Dann würde es aber ja reichen, für jeden Container auch einen Mutex zu instantiieren und den dann immer von Hand zu locken (darf man dann halt nie vergessen...).

    Nicht von Hand. Wir sind im neuen Millenium. C++ mit RAII statt good ol' C 🙂
    Sprich: Sowas wie ein scoped_lock (siehe boost::thread), scope_guard bzw. LockingPtr(siehe Artikel von A. Alexandrescu) oder eines der vielen anderen "Executing Around"-Patterns (siehe z.B. Kevlin Henney: Executing Around Sequences) sind da besser geeignet.



  • Um das loggen deiner container wirst ned umhinkommen, das nimmt dir keine Threadsichere Lib ab ! die frage ist halt nur, was von deinem container ueberbleibt, wenn du nen gleichzeitig konkurrierenden zugriff ausversehen doch noch hast :p

    Bei der MS Impl der STL weiss ich nur so viel, das es probleme mit dem MT gab, weil die COntainerklassen auf globale ausserhalb der stl klasse definierten variablen zugegriffen haben, und es so zu seiteneffekten kam ... was teilweisse zu nicht vorraussehbaren verhalten gefuehrt hat ....
    Laso die probleme traten nicht auf, wenn gleichzeitig auf den gleichen container zugegriffen wurde (ok, probleme gabs da auch, aber das hat jede impl 🙂 ) sondern wenn gleichzeitig auf unterschiedliche container des gleichen types zugegriffen wurde (nicht immer, aber immer oefter) und da auch nur in speziellen faellen ... War zumindest bei VS 6.0 so !

    STLPort ist ne alternative, kann ich nur empfehlen ...

    Ciao ...



  • Hi,

    OK, danke für eure Antworten! Wenn es nicht geht, melde ich mich nochmal 🙂

    ChrisM



  • Hi,

    so, ich hab jetzt wirklich alles probiert, aber ich kriege es einfach nicht hin, die Boost-Threadlibrary bei mir (MSVC .net 2003 Prof) mit Boost.Jam und den Kommandozeilentools meines Compilers zu builden. Ich weiß nicht, woran es liegt, aber ich kriege nur "Nicht gefunden"-Fehler von jam.exe (hab mir die neuste vorcompilierte Version von der SourceForge-Downloadpage von Boost heruntergeladen). 😞 😞

    ChrisM



  • Hi,

    *push*

    ChrisM



  • Hi,

    OK, ich hab es jetzt geschafft, ich habe Boost meinem Projekt hinzugefügt (also nur Boost.Thread), den Boostincludeordner zu den Standard-Includeordnern meines Compilers (bzw. Präprozessor) und zur Multithreaded DLL-Laufzeitbibliothek gewechselt.

    Er compiliert zwar, aber ich kriege einen riesigen Berg an Warnungen: (hier ein kleiner Ausschnit)

    ...
    thread.cpp
    c:\boost\boost\thread\exceptions.hpp(29) : warning C4275: class 'std::logic_error' ist keine DLL-Schnittstelle und wurde als Basisklasse für die DLL-Schnittstelle class 'boost::lock_error' verwendet
    c:\Programme\Microsoft Visual Studio .NET 2003\Vc7\include\stdexcept(14): Siehe Deklaration von 'std::logic_error'
    c:\boost\boost\thread\exceptions.hpp(28): Siehe Deklaration von 'boost::lock_error'
    c:\boost\boost\thread\exceptions.hpp(35) : warning C4275: class 'std::runtime_error' ist keine DLL-Schnittstelle und wurde als Basisklasse für die DLL-Schnittstelle class 'boost::thread_resource_error' verwendet
    c:\Programme\Microsoft Visual Studio .NET 2003\Vc7\include\stdexcept(136): Siehe Deklaration von 'std::runtime_error'
    c:\boost\boost\thread\exceptions.hpp(34): Siehe Deklaration von 'boost::thread_resource_error'
    c:\boost\boost\thread\mutex.hpp(37) : warning C4275: class 'boost::noncopyable' ist keine DLL-Schnittstelle und wurde als Basisklasse für die DLL-Schnittstelle class 'boost::mutex' verwendet
    c:\boost\boost\noncopyable.hpp(22): Siehe Deklaration von 'boost::noncopyable'
    c:\boost\boost\thread\mutex.hpp(36): Siehe Deklaration von 'boost::mutex'
    c:\boost\boost\thread\mutex.hpp(75) : warning C4275: class 'boost::noncopyable' ist keine DLL-Schnittstelle und wurde als Basisklasse für die DLL-Schnittstelle class 'boost::try_mutex' verwendet
    c:\boost\boost\noncopyable.hpp(22): Siehe Deklaration von 'boost::noncopyable'
    c:\boost\boost\thread\mutex.hpp(74): Siehe Deklaration von 'boost::try_mutex'
    c:\boost\boost\thread\mutex.hpp(115) : warning C4275: class 'boost::noncopyable' ist keine DLL-Schnittstelle und wurde als Basisklasse für die DLL-Schnittstelle class 'boost::timed_mutex' verwendet
    c:\boost\boost\noncopyable.hpp(22): Siehe Deklaration von 'boost::noncopyable'
    c:\boost\boost\thread\mutex.hpp(114): Siehe Deklaration von 'boost::timed_mutex'
    c:\boost\boost\thread\thread.hpp(39) : warning C4275: class 'boost::noncopyable' ist keine DLL-Schnittstelle und wurde als Basisklasse für die DLL-Schnittstelle class 'boost::thread' verwendet
    c:\boost\boost\noncopyable.hpp(22): Siehe Deklaration von 'boost::noncopyable'
    c:\boost\boost\thread\thread.hpp(38): Siehe Deklaration von 'boost::thread'
    c:\boost\boost\thread\thread.hpp(68) : warning C4275: class 'boost::noncopyable' ist keine DLL-Schnittstelle und wurde als Basisklasse für die DLL-Schnittstelle class 'boost::thread_group' verwendet
    c:\boost\boost\noncopyable.hpp(22): Siehe Deklaration von 'boost::noncopyable'
    c:\boost\boost\thread\thread.hpp(67): Siehe Deklaration von 'boost::thread_group'
    c:\boost\boost\thread\thread.hpp(79) : warning C4251: 'boost::thread_group::m_threads': class 'std::list<_Ty>' erfordert eine DLL-Schnittstelle, die von Clients von class 'boost::thread_group' verwendet wird
    with
    [
    _Ty=boost::thread *
    ]
    c:\boost\boost\thread\condition.hpp(38) : warning C4275: class 'boost::noncopyable' ist keine DLL-Schnittstelle und wurde als Basisklasse für die DLL-Schnittstelle class 'boost::detail::condition_impl' verwendet
    c:\boost\boost\noncopyable.hpp(22): Siehe Deklaration von 'boost::noncopyable'
    c:\boost\boost\thread\condition.hpp(37): Siehe Deklaration von 'boost::detail::condition_impl'
    d:\Daten\Programmieren\Projekte\Galactic Blast\Shared\Boost\thread.cpp(90) : warning C4273: 'boost::thread::thread': Inkonsistente DLL-Bindung.
    d:\Daten\Programmieren\Projekte\Galactic Blast\Shared\Boost\thread.cpp(106) : warning C4273: 'boost::thread::thread': Inkonsistente DLL-Bindung.
    d:\Daten\Programmieren\Projekte\Galactic Blast\Shared\Boost\thread.cpp(143) : warning C4273: 'boost::thread::~thread': Inkonsistente DLL-Bindung.
    ...

    Woran könnte das liegen? (die Boostdateien sind gar nicht zu einem DLL-Projekt, sondern zu einer ganz normalen statischen Lib hinzugefügt worden)

    ChrisM



  • Hi,

    *push*

    mit dem Posting eben hat er den Thread gar nicht hochgeholt und danach war die Datenbank 5 Minuten down 😕

    ChrisM


Anmelden zum Antworten