@Zaher220
Software developer

Утечка памяти при блокировке std::mutex?

Здравствуйте.
Столкнулся с утечкой памяти при работе с потоками.
Мне понадобилось сделать класс который в отдельном потоке насчитывает данные. Для этого в классе создал объект типа std::thread и ему передал функцию член класса, в которой ведётся непрерывная обработка. Другой функцией периодически забираю полученные данные.
Ниже пример кода который очевиднее любых объяснений. На него я натравил Intel Inspector XE 2015.
На выходе получил
ID Type Sources Modules Object Size State
Missing allocation xthread:68 threadtest.exe Not fixed
Утечка памяти при залочивании мьютекса
void mycl::start(){
		<b>m.lock();</b>
....


class mycl{
public:
	mycl():m_thread()
	{
		for (int i = 0; i < 5; i++)
			data.push_back(i);
	}
	~mycl(){
		if (m_thread.joinable())
			m_thread.join();
	}
	std::vector<float> mycl::getData()
	{
std::vector<float> d;
		m.lock();
		printf("get data\n");
		for (unsigned int i = 0; i < data.size(); i++){
			printf("%f ", data.at(i));
		}
		printf("\n");
		d = data;
		m.unlock();
		return d;
	}

	void mycl::process(bool& stat)
	{
		while (true){
			std::vector<float> d;
			m.lock();
			if (!stat)
			{
				m.unlock();
				return;
			}
			for (int i = 0; i < data.size(); i++){
				d.push_back(50 * 20 * rand());
			}
			data = d;
			m.unlock();
		}
	}

	void mycl::start(){
		m.lock();
		started = true;
		m.unlock();
		m_thread = std::thread(&mycl::process, this, std::ref(started));

	}
	void mycl::stop(){
		m.lock();
		started = false;
		m.unlock();
		if (m_thread.joinable())
			m_thread.join();
	}
private:
	std::vector<float> data;
	bool started = false;
	std::thread m_thread;
	std::mutex m;
};

void main(){
	mycl cl;
	srand(time(NULL));
	cl.start();
	std::vector<float> vc;
	for (int i = 0; i < 1000; i++){
		vc = cl.getData();
	}
	cl.stop();
}

Хотелось бы увидеть пример действительно потокобезопасного класса.
  • Вопрос задан
  • 2486 просмотров
Пригласить эксперта
Ответы на вопрос 3
gbg
@gbg Куратор тега C++
Любые ответы на любые вопросы
Честно говоря, код дрянной, начиная с путаницы int/uint и игнорирования итераторов, и заканчивая логической переменной, обернутой во мьютекс.

Смысла в данной логической переменной на данный момент не видно.

Вот этот кусок:
printf("get data\n");
    for (unsigned int i = 0; i < data.size(); i++){
      printf("%f ", data.at(i));
    }
    printf("\n");
    std::vector<float> d;
    m.lock();
    d = data;
    m.unlock();
    return d;

просится на известный сайт на букву G, потому как здесь сначала в наглую ковыряются в массиве data, не соизволив запереть его на мьютекс. Возможно, это вырождение произошло во время отладки.

Вопрос к автору - зачем нужен флаг started?

"Утечку" какого-либо ресурса этот код порождать не может, потому как не создает динамических объектов.
Ответ написан
tsarevfs
@tsarevfs Куратор тега C++
C++ developer
Пока вы печатаете data в getData(), поток может его поменять. Используйте для этого локальную копию d. Не совсем понятно зачем передавать started как параметр.
Ответ написан
Комментировать
AxisPod
@AxisPod
Как вариант вместо мутекса и установки значения лучше бы использовать std::atomic_flag или std::atomic, первый попроще в возможностях, но 100% атомарен на любых системах, второй побольше возможностей имеет. Ну и в некоторых случаях может хватить переменной помеченной как volatile.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы