Бесконечный цикл прерывается в release билде

230
07 февраля 2020, 15:10

Есть следующий код:

class A {
    public:
        void exec();
    private:
        std::list<std::vector<uint32_t>> valuesStores;
        std::mutex mutex;
        uint32_t currentBufferFullness = 0;
        static const int maxNumOfValues = 1000;
};
void A::exec() {
    std::cout << "start\n";
    srand(time(NULL));
    for (auto i = 0; i < 10; ++i) {
        valuesStores.emplace_back(std::vector<uint32_t>());
        problemMethod();    //Метод, в котором возникает проблема
        if (valuesStores.back().size()) {
            mutex.lock();
            auto valuesIter = valuesStores.end();
            std::thread thread([this](auto valuesStoreIter) {
                    //Над valuesStoreIter производятся некие длительные операции
                    using namespace std::chrono_literals;
                    std::cout << "We go to bed\n";
                    std::this_thread::sleep_for(2s);
                    std::cout << "We wake up\n";
                    mutex.lock();
                    currentBufferFullness -= valuesStoreIter->size();
                    valuesStores.erase(valuesStoreIter);
                    mutex.unlock();
                }, --valuesIter);
            thread.detach();
            mutex.unlock();
        }
    }
    std::cout << "end\n";
}
void A::problemMethod() {
    for (auto j = 0; j < (maxNumOfValues / 2); ++j) {
        while (maxNumOfValues <= currentBufferFullness) {   //Проблема возникает тут
        }
        valuesStores.emplace_back(rand() % 1000);
        mutex.lock();
        ++currentBufferFullness;
        mutex.unlock();
    }
}
int main() {
    A a;
    a.exec();
    return 0;
}

Тут имеется некоторый метод problemMethod, выполняющийся в основном потоке, в котором осуществляется, считывание данных. По завершению выполнения метода, эти данные передаются в поток, в котором они будут как-либо обработаны, а пока идёт обработка, вновь вызывается метод problemMethod и считываются следующие данные. Когда значение некоего счётчика currentBufferFullness окажется больше или равно предельному значению, я ожидаю, когда какой нибудь из потоков освободит память из под переданных ему данных, после чего продолжаю считывание.

Данный алгоритм работает в debug билде (мною используется MinGW730_64), однако, при переключении в release, зацикливание завершается после пары первых итераций (между ними цикл не работает в холостую). Пока искал ошибку, предположил, что счётчик currentBufferFullness криво сбрасывается и цикл зацикливается окончательно, в итоге пришёл к следующему коду:

void A::problemMethod() {
    for (auto j = 0; j < (maxNumOfValues / 2); ++j) {
        while (true) {
            static auto justACrutchCounter = 0;
            if (UINT_MAX <= justACrutchCounter++) {
                std::cout << "";
            }
            if (maxNumOfValues > currentBufferFullness) {
                break;
            }
        }
        valuesStores.emplace_back(rand() % 1000);
        mutex.lock();
        ++currentBufferFullness;
        mutex.unlock();
    }
}

Потенциально пройти по положительной ветке, в которой должен быть выведен поток, возможно (хоть это и не так) и теперь цикл имеется постоянную нагрузку, не позволяющую скипнуть его работу.

Благодаря такому костылю цикл не прерывается, что хорошо, но выглядит это ещё хуже, чем было до него, да и хотелось бы разобраться, с чем связана такая работа цикла в release билде и что с этим делать.

READ ALSO
Сколько раз функция может вызвать саму себя? C/C++

Сколько раз функция может вызвать саму себя? C/C++

Сколько раз функция может вызвать саму себя и от чего это зависит

208
Ошибка Thread 1: EXC_BAD_ACCESS (code=1, address=0x0) при компиляции

Ошибка Thread 1: EXC_BAD_ACCESS (code=1, address=0x0) при компиляции

Необходимо написать класс для работы с целыми знаковыми числами с использованием stl и виртуальных функций(С++03)

203
Аппаратный генератор случайных чисел

Аппаратный генератор случайных чисел

Нашел в интернете код, где используется аппаратный генератор случайных чиселХабр

203
как разделить очень очень длинное число, такое как Фибоначчи на очень мелкие части

как разделить очень очень длинное число, такое как Фибоначчи на очень мелкие части

Дело в том что мой код не может отобразить все число даже unsigned long long кажется очень мелким, я думаю использовать int и разделения между длиной...

184