Добрый день всем! В ходе работы с многопоточностью в C++ у меня возникли некоторые проблемы. Я качаю некоторые данные(файлы небольшого размера) с некоторого ресурса в многопоточном режиме и сохраняю их все в одну директорию. Когда файлов накапливается в директории очень много(скажем порядка 100000) я хочу создавать новую директорию и перемещать файлы туда. Таким образом у меня получится несколько директорий, каждая из которых содержит по 100000 файлов.
Вот примерный код
#include <boost/thread.hpp>
#include <boost/thread/barrier.hpp>
#include <boost/bind.hpp>
#include <boost/atomic.hpp>
...
void handler(std::list<std::string> &must_donwloaded, boost::mutex &m, boost::atomic<int> &count_donwloaded)
{
for (auto it = must_downloaded.begin(); it != must_downloaded.end(); it++
{
std::string url_to_file = *it;
//здесь я делаю запрос к ресурсу и выкачиваю файл
//после получения файла я его сохраняю в дирректорию
....
//инкрементирую переменную real_downloaded
real_downloaded++;
}
}
int main(int argc, char** argv)
{
boost::mutex m;
boost::atomic<int> real_downloaded(0);
//url-ы в списках полностью уникальны. Т.е все они разные
std::list<std::string> md1 = {"..", "..", "..", ..};
std::list<std::string> md2 = {"..", "..", ..};
std::list<std::string> md3 = {"..", "..", "..", "..", ..};
boost::thread thr1(boost::bind(&handler, boost::ref(md1), boost::ref(m), boost::ref(real_downloaded)));
boost::thread thr2(boost::bind(&handler, boost::ref(md2), boost::ref(m), boost::ref(real_downloaded)));
boost::thread thr3(boost::bind(&handler, boost::ref(md3), boost::ref(m), boost::ref(real_downloaded)));
thr1.join();
thr2.join();
thr3.join();
return 0;
}
В голову приходит следующие.
В функции-обработчике проверять каждый раз переменную real_downloaded
и если она равна 100000, то вызывать функцию создания новой директории и перемещать файлы в новую директорию. Но что-то мне подсказывает, что это плохой способ, т.к может возникнуть ситуация, когда один поток сохраняет файл, а тот поток, в котором выполнилось условие real_downloaded==100000
будет пытаться переместить сохраняемый файл в другую директорию.
Подскажите, как мне обойтись здесь и изменить код, чтобы он был потокобезопасным? Нужно не допустить приведенный выше ситуации. Спасибо.
Перемещать ничего не нужно. Вы можете закрыть функцию, которая создает новый файл мьютексом. Внутри нее ведите подсчет созданных файлов. Когда количество перевалит за N - создаете новую директорию и начинаете писать файлы в нее.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
В другом вопросе обнаружилось, что деление нуля на переменную, содержащую вещественный ноль, в результате даёт значение -nan
Задача следующая: необходимо на C/C++ получить список подключенных к ПК на Linux подключенных USB-устройств