Jak se mohu ujistit, že je tam jen jeden mutex?

hlasů
2

Jsem běží nějaké vlákno bezpečný kód zde. Já používám mutex chránit část kódu, který musí být spuštěn jen o pouhé 1 nití najednou. Problém jsem se pomocí tohoto kódu někdy skončit s 2 mutexu objekty. To je statická funkce mimochodem. Jak se mohu ujistit, že pouze jeden objekt mutex dostane vytvořil ??

/*static*/ MyClass::GetResource()
{

if (m_mutex == 0)
{
// make a new mutex object
m_mutex = new MyMutex();
}

m_mutex->Lock();
Položena 27/08/2009 v 02:23
zdroj uživatelem
V jiných jazycích...                            


5 odpovědí

hlasů
12

Jednoduše vytvořit m_mutexmimo GetResource(),předtím to může být někdy nazýván - to odstraní kritické sekce kolem skutečné vytvoření mutex.

MyClass::Init()
{
  m_mutex = new Mutex;
}    

MyClass::GetResource()
{
  m_mutex->Lock();
  ...
  m_mutex->Unlock();
}
Odpovězeno 27/08/2009 v 02:30
zdroj uživatelem

hlasů
8

Otázkou je nit mohla být přerušena po kontrole, zda m_mutex je 0, ale ne dříve, než vytvoří mutex, který umožňuje další vlákno projít stejným kódem.

Nenechte přiřadit m_mutex hned. Vytvořte nový objekt mutex, a pak to atomový porovnat výměnu.

Nemusíte zmínit svou cílovou platformu, ale v systému Windows:

MyClass::GetResource()
{
    if (m_mutex == 0)
    {
        // make a new mutex object
        MyMutex* mutex = new MyMutex();

        // Only set if mutex is still NULL.
        if (InterlockedCompareExchangePointer(&m_mutex, mutex, 0) != 0)
        {
           // someone else beat us to it.
           delete mutex;
        }
    }
    m_mutex->Lock();

V opačném případě nahradit s tím, co můžete porovnat / odkládací funkci váš operační systém poskytuje.

Další možností je použít inicializační jednorázovou podporu, která je k dispozici v systému Windows Vista a vyšší, nebo pokud je to možné jen předem vytvořit mutex.

Odpovězeno 27/08/2009 v 02:27
zdroj uživatelem

hlasů
3

Lazy inicializace mutex není příliš vhodný pro statické metody; budete potřebovat nějakou záruku, že nikdo závodů na inicializaci. Doplňuje se používá kompilátor generovat jeden statický mutex pro třídu.

/* Header (.hxx) */
class MyClass
{
    ...

  private:
    static mutable MyMutex m_mutex;  // Declares, "this mutex exists, somewhere."
};


/* Compilation Unit (.cxx) */
MyMutex MyClass::m_mutex;            // The aforementioned, "somewhere."

MyClass::GetResource()
{
    m_mutex.Lock();
    ...
    m_mutex.Unlock();
}

Některá jiná řešení bude vyžadovat další předpoklady svými kolegy programátory. S „volání init ()“ metody, například, musíte být jisti, že metoda inicializace byli voláni, a každý by měl vědět toto pravidlo.

Odpovězeno 27/08/2009 v 02:45
zdroj uživatelem

hlasů
2

Proč používat ukazatel vlastně je? Proč ne nahradit ukazatel s aktuálním instance, který nevyžaduje dynamickou správu paměti? Tím se zabrání spor, a neukládá hit výkon na každé volání do funkce.

Odpovězeno 27/08/2009 v 02:35
zdroj uživatelem

hlasů
0

Vzhledem k tomu, že je pouze chránit jednu specifickou část kódu, jednoduše prohlásit ho za statickou uvnitř funkce.

static MyClass::GetResource()
{
    static MyMutex mutex;

    mutex.Lock();
    // ...
    mutex.Unlock();

Proměnná je lokální proměnná se statickým trvání skladování. To je výslovně uvedeno ve standardu:

Implementace je povoleno provádět včasné inicializaci jiné blokové působnosti proměnných se statickým nebo závitem dobu skladování za stejných podmínek, že implementace je povoleno staticky inicializovat proměnnou statickou nebo závitem dobu skladování v rámci oboru názvů (3.6.2). V opačném případě je taková proměnná inicializovat poprvé kontrola prochází jeho prohlášení; taková proměnná je považován inicializuje po dokončení jeho inicializace. V případě, že inicializace východy podle vyvolání výjimky, inicializace není kompletní, takže to bude souzen opět příští časové kontroly vstoupí do prohlášení. Pokud je řídicí vstoupí prohlášení současně zatímco proměnná je inicializována, musí souběžné spuštění počkat na dokončení inicializace.

Poslední věta je obzvláště zajímavé pro vás.

Odpovězeno 20/02/2014 v 13:09
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more