web-dev-qa-db-fra.com

C ++ 11 mutex de lecture multiple et un thread d'écriture

J'ai une application, où certains conteneurs STL sont lus en 3 threads et écrits en 2. Je sais qu'il y a TBB pour les conteneurs multi-threads, mais ce n'est pas une option dans mon application.

Je veux donc rendre le programme thread-safe en utilisant std :: mutex et à mains nues. Ceci est une version simple de ce que j'ai fait:

int readers = 0;
std::mutex write;

// One write, no reads.
void write_fun()
{
    write.lock();// We lock the resource
    while(readers > 0){}// We wait till everyone finishes read.
    // DO WRITE
    write.unlock();// Release
}

// Multiple reads, no write
void read_fun()
{
    // We wait if it is being written.
    while(!write.try_lock()){}
    write.unlock();

    readers++;
    // do read
    readers--;
}

Est-ce la bonne façon de procéder en C++ 11?

23
VSZM

Assez proche, quelques choses à noter, en c ++ pour une sécurité et une lisibilité exceptionnelles, IMO, il est bon d'utiliser des verrous RAII. Ce dont vous avez vraiment besoin, c'est d'un shared_mutex comme dans boost ou venant en c ++ 14.

std::shared_mutex write; //use boost's or c++14 

// One write, no reads.
void write_fun()
{
    std::lock_guard<std::shared_mutex> lock(write);
    // DO WRITE
}

// Multiple reads, no write
void read_fun()
{
    std::shared_lock<std::shared_mutex> lock(write);
    // do read
}

Si vous ne voulez pas utiliser boost @howardhinmant a été gentil de donner un lien vers un implémentation de référence

37
aaronman

Ceci est sûr, mais n'est probablement pas juste ou performant:

std::atomic<int> readers;
std::mutex write;

// One write, no reads.
void write_fun()
{
    write.lock();// We lock the resource
    while(readers > 0){}// We wait till everyone finishes read.
    // DO WRITE
    write.unlock();// Release
}

// Multiple reads, no write
void read_fun()
{
    // We wait if it is being written.
    write.lock();
    readers++;
    write.unlock();

    // do read
    readers--;
}

Une solution avec des variables de condition pourrait éviter d'attendre que readers tombe à 0, laissé comme exercice pour le lecteur.

8
Casey