Есть следующий код:
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 билде и что с этим делать.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Сколько раз функция может вызвать саму себя и от чего это зависит
Необходимо написать класс для работы с целыми знаковыми числами с использованием stl и виртуальных функций(С++03)
Нашел в интернете код, где используется аппаратный генератор случайных чиселХабр
Дело в том что мой код не может отобразить все число даже unsigned long long кажется очень мелким, я думаю использовать int и разделения между длиной...