keker123

Untitled

Apr 1st, 2023 (edited)
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.20 KB | None | 0 0
  1. #include <thread>
  2. #include <mutex>
  3.  
  4.  
  5. #include <vector>
  6. #include <queue>
  7. #include <functional>
  8. #include <condition_variable>
  9. #include <atomic>
  10. #include <filesystem>
  11. #include "iostream"
  12. #include "future"
  13. /*
  14.     Вам необходимо написать функцию, которая используя std::filesystem
  15.     Рекурсивно обойдет все поддериктории данной директории.
  16.     На каждый файл зовет функцию callback.
  17. */
  18.  
  19. //void CheckDir(ThreadPool& pool, fs::path dir);
  20. //// Вызывает ls папки dir
  21. // Далее, как будет готов результат, обрабатываем в busy-loop результаты
  22. // 1)если папка - позвать ls
  23. // 2)если симлинк - не делать ничего
  24. // 3)если файл - позвать callback
  25. //  - одновременно мы ждем результаты нескольких запросов ls
  26.  
  27. // /* some type*/ ls(fs::path path, ThreadPool& pool);
  28. // отправляет команду в thread_pool на ls директорииш
  29. // Само обращение к filesystem должно происходить в thread_pool. Почему?
  30. // в ответ мы должны узнать список файлов/папок/симлинок в этой папке
  31.  
  32. //чтобы проверить, исполнена задача или нет
  33. //if(future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
  34. //  получение и обработка результата
  35. //}
  36.  
  37. //Необходимые функции из std::filesystem
  38. //for (const auto& entity : fs::directory_iterator(path)) - обойти все файлы и папки в директории
  39. //bool fs::is_directory(fs::path) - вернет true если папка
  40. //bool fs::is_symlink(fs::path) аналогично
  41. //fs::path path - путь. можно выводить в cout
  42.  
  43.  
  44. //Вам дан готовый ThreadPool, который надо использовать для решения задачи
  45. class ThreadPool {
  46. public:
  47.     ThreadPool(size_t threadCount) : active_(true) {
  48.         for (size_t i = 0; i < threadCount; ++i) {
  49.             threads_.emplace_back([&]() { ThreadFunction(); });
  50.         }
  51.     }
  52.  
  53.     void PushTask(std::function<void()> task) {
  54.         if (!active_) {
  55.             throw std::exception();
  56.         }
  57.         {
  58.             std::lock_guard<std::mutex> lockGuard(tasksMutex_);
  59.             tasksQueue_.push(task);
  60.         }
  61.         taskPushed_.notify_one();
  62.     }
  63.  
  64.     void Terminate() {
  65.         active_ = false;
  66.         taskPushed_.notify_all();
  67.         for (auto &thread: threads_) {
  68.             thread.join();
  69.         }
  70.     }
  71.  
  72.     bool IsActive() const {
  73.         return active_;
  74.     }
  75.  
  76.     size_t QueueSize() const {
  77.         std::lock_guard<std::mutex> lock(tasksMutex_);
  78.         return tasksQueue_.size();
  79.     }
  80.  
  81. private:
  82.     std::vector<std::thread> threads_;
  83.     std::queue<std::function<void()>> tasksQueue_;
  84.     mutable std::mutex tasksMutex_;
  85.     std::condition_variable taskPushed_;
  86.     std::atomic<bool> active_;
  87.  
  88.     void ThreadFunction() {
  89.         while (true) {
  90.             std::unique_lock<std::mutex> lock(tasksMutex_);
  91.             while (tasksQueue_.empty()) {
  92.                 if (!active_) {
  93.                     return;
  94.                 }
  95.                 taskPushed_.wait(lock);
  96.             }
  97.             auto task = tasksQueue_.front();
  98.             tasksQueue_.pop();
  99.             lock.unlock();
  100.             task();
  101.         }
  102.     }
  103. };
  104.  
  105. //////////////////////////////////////////////////////////
  106.  
  107. namespace fs = std::filesystem;
  108.  
  109.  
  110. void callback(fs::path path) {
  111.     std::cout << path << std::endl;
  112. }
  113.  
  114. std::future<std::vector<fs::path>> ls(const fs::path &path, ThreadPool &pool) {
  115.     std::shared_ptr<std::promise<std::vector<fs::path>>> promiseResult = std::make_shared<std::promise<std::vector<fs::path>>>();
  116.     auto future = promiseResult->get_future();
  117.     auto task = [promiseResult, &pool, path]() {
  118.         std::vector<fs::path> dirs;
  119.         for (const auto &i: fs::directory_iterator(path)) {
  120.             dirs.push_back(i);
  121.         }
  122.         promiseResult->set_value(std::move(dirs));
  123.     };
  124.     pool.PushTask(std::move(task));
  125.     return future;
  126. }
  127.  
  128. void CheckDir(ThreadPool &pool, fs::path dir) {
  129.     std::queue<std::future<std::vector<fs::path>>> queue;
  130.     queue.push(ls(std::move(dir), pool));
  131.     while (queue.size() != 0) {
  132.         auto front = std::move(queue.front());
  133.         if (front.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
  134.             auto dirs = front.get();
  135.             for (const auto &it: dirs) {
  136.                 if (fs::is_directory(it)){
  137.                     queue.push(ls(std::move(it), pool));
  138.                 } else if (!fs::is_symlink(it)){
  139.                     callback(it);
  140.                 }
  141.             }
  142.         } else {
  143.             queue.push(std::move(front));
  144.             queue.pop();
  145.         }
  146.     }
  147. }
  148.  
  149. int main() {
  150.     ThreadPool pool(3);
  151.     CheckDir(pool, "./../"); // отсчитывает от папки с исполняемым файлом
  152.     pool.Terminate();
  153. }
  154.  
Advertisement
Add Comment
Please, Sign In to add comment