Безопасен ли следующий пример кода std :: queue? - PullRequest
0 голосов
/ 09 марта 2020

У меня есть следующий пример кода, и я не уверен, является ли он потокобезопасным.

void remove(/*...*/) {
    int a;
    float* data;

    while (true)
    {
        unique_lock<mutex> lock1(mu);
        cond.wait(lock1, [this](){return count > 0;});
        lock1.unlock();

        a = std_queue1.front();

        data = std_queue2.front();

        // process data

        unique_lock<mutex> lock2(mu);
        std_queue1.pop();
        std_queue2.pop();
        count--;
        lock2.unlock();
        cond.notify_all();
    }
}

void add(/*...*/){
    int a, iterations = 0;
    vector<float*> data;
    // Allocate some data entries
    while (true) {
        // set a
        unique_lock<mutex> lock1(mu);
        std_queue1.push(a);
        cond.wait(lock1, [this, &limit]() { return count < limit; });
        lock1.unlock();

        // Init data

        if (iterations++ > 2) {
            unique_lock<mutex> lock2(mu);
            std_queue2.push(data[/*...*/]);
            count++;
            lock2.unlock();
            cond.notify_all();
        }
    }
}

remove (...) и add (...) являются функциями одного класса. Каждая функция выполняется одним потоком, и оба потока получают доступ к одним и тем же очередям. Мьютекс заблокирован для pu sh и извлекает данные из очередей, но не для функции front ().

Итак, мой вопрос: безопасен ли этот пример потока? Или мне нужен мьютекс для функции front ()? И нужен ли мьютекс для функций pop () и pu sh ()?

1 Ответ

2 голосов
/ 09 марта 2020

Итак, мой вопрос: безопасен ли этот пример потока?

Нет.

Или мне нужен мьютекс для функции front ()?

Да.

И необходим ли мьютекс для функций pop () и pu sh ()?

Да.

Изменение стандартного контейнера не гарантирует безопасность потоков.

...