Подтвердить что ты не робот

С++ 11 многопользовательского чтения и один мьютекс потока записи

У меня есть приложение, где некоторые контейнеры STL читаются в 3 потоках и написаны в 2. Я знаю, что для многопоточных контейнеров есть TBB, но это не вариант в моем приложении.

Итак, я хочу сделать программу потокобезопасной, используя std:: mutex и мои голые руки. Это простая версия того, что я сделал:

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--;
}

Это правильный способ сделать это в С++ 11?

4b9b3361

Ответ 1

Довольно близко, пара вещей, чтобы отметить, в С++ для безопасности и удобочитаемости исключений, IMO, полезно использовать блокировки RAII. То, что вам действительно нужно, это shared_mutex, например, в boost или в С++ 14.

std::shared_mutex write; //use boost 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
}

Если вы не хотите использовать boost @howardhinmant, он сделал вид, чтобы дать ссылку на справочную реализацию

Ответ 2

Это безопасно, но, вероятно, не справедливо или честно:

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--;
}

Решение с переменными условия могло бы избежать занятости, ожидая, пока readers упадет до 0, оставив в качестве упражнения для читателя.