Проблема с потоками c++

84
18 декабря 2021, 04:50

впервые работаю с потоками и возникла проблема в синхронизации.

Имею следующий код:

typedef int Request;
std::mutex                       g_mutex;
Generator                        g_gen(150,100);
bool                             RequestIsExpecting=true;
int ReqAdded = 0;
int ReqNeed= 10;
std::deque<Request> ReqQueue;
int FailReqCount = 0;
int ReqLimit = 48;
void AddRequest();
void AddRequest();
bool RequestIsExpecting=true;
std::deque<Request> ReqQueue;
void Worker(int& ReqAcceptedCount)
{
    while(RequestIsExpecting || !ReqQueue.empty())
    {   
        if(ReqQueue.empty())
            continue;
        Request WorkTime;
        g_mutex.lock();
        WorkTime = ReqQueue.front();
        ReqQueue.pop_front();
        g_mutex.unlock();
        ReqAcceptedCount++;
        std::this_thread::sleep_for(std::chrono::microseconds(WorkTime));
    }
}
int main()
{
    int Worker1ReqCount = 0;
    std::thread Worker1(Worker,std::ref(Worker1ReqCount));
    int Worker2ReqCount = 0;
    std::thread Worker2(Worker, std::ref(Worker2ReqCount));
    
    AddRequest();
    RequestIsExpecting = false;
    if (Worker1.joinable())
        Worker1.join();
    if (Worker2.joinable())
        Worker2.join();
    std::cout << Worker1ReqCount;
    std::cout << Worker2ReqCount;
}

void AddRequest()
{
    while (ReqAdded != ReqNeed)
    {
        if(ReqQueue.size()>=ReqLimit)
        {
            FailReqCount++;
            std::this_thread::sleep_for(std::chrono::microseconds(g_gen.next()));
            continue;
        }
        g_mutex.lock();
        
        ReqQueue.push_back(g_gen.next());
        ReqAdded++;
        g_mutex.unlock();
        std::this_thread::sleep_for(std::chrono::microseconds(g_gen.next()));
    }
}

С одним "рабочим" программа работает нормально, ошибка возникает при появлении второго рабочего в коде. Видимо, напутал где-то с мьютексами в функции Worker или что-то не сделал дополнительно.

Answer 1

Любые обращения к общему контейнеру должны быть огорожены мьютексом. Представьте, что в то время, пока делается pop(), вы начали проверять empty() - результат будет "как повезет".

READ ALSO
Выход из бесконечного цикла без команды ввода

Выход из бесконечного цикла без команды ввода

Реально ли сделать выход из цикла без команды ввода? Допустим идет бесконечный цикл и в любой момент я нажимаю ENTER и цикл прекращаетсяЕсли...

104
Как вывести значения цикла после окончания

Как вывести значения цикла после окончания

Ребят, не подскажете, как сделать вывод из цикла итогового значения i,k,j? Пробовал через присваивания другим переменным, но они остаются локальными...

185
Сортировка динамической структуры

Сортировка динамической структуры

У меня есть структура данных

174
Как найти элементы с заданным условием C# LINQ

Как найти элементы с заданным условием C# LINQ

Есть массив элементов типа int, например {-50, 2, 55, 985, 98515, -5354}

191