Advertisement
zhangsongcui

ThreadPool v1.1

Jul 31st, 2016
204
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.30 KB | None | 0 0
  1. #include <iostream>
  2. #include <thread>
  3. #include <vector>
  4. #include <queue>
  5. #include <algorithm>
  6. #include <map>
  7. #include <string>
  8. #include <condition_variable>
  9. #include <mutex>
  10.  
  11. std::condition_variable condDoTask, condOutput;
  12. std::mutex globalMutex, encodeMutex, outputMutex;
  13.  
  14. volatile bool isMissionComplete = false;
  15.  
  16. void Encode(std::queue<std::pair<unsigned, std::string>>& in, std::map<unsigned, std::string>& out)
  17. {
  18.     while (true)
  19.     {
  20.         std::unique_lock<std::mutex> lock(encodeMutex);
  21.         condDoTask.wait(lock, [&in] { return !in.empty() || isMissionComplete; });
  22.         if (isMissionComplete)
  23.             break;
  24.         globalMutex.lock();
  25.         std::pair<unsigned, std::string> deal(std::move(in.front()));
  26.         globalMutex.unlock();
  27.         in.pop();
  28.         ///////// DO YOUR TASK HERE //////////
  29.         std::for_each(deal.second.begin(), deal.second.end(),
  30.             [] (char& c) { c = std::isupper(c) ? std::tolower(c) : std::toupper(c); } );
  31.         ///////// DO YOUR TASK HERE //////////
  32.         globalMutex.lock();
  33.         out.insert(std::move(deal));
  34.         globalMutex.unlock();
  35.         condOutput.notify_all();
  36.     }
  37.     condOutput.notify_all();
  38. }
  39.  
  40. void Output(std::map<unsigned, std::string>& out, const volatile unsigned& total)
  41. {
  42.     unsigned count = 0;
  43.     while (true)
  44.     {
  45.         std::unique_lock<std::mutex> lock(outputMutex);
  46.         condOutput.wait(lock,
  47.             [&out, count, &total] { return (!out.empty() && count == out.begin()->first) || ( isMissionComplete && count == total); });
  48.         if (isMissionComplete && count == total)
  49.             break;
  50.         std::cout << out.begin()->second << std::endl;
  51.         globalMutex.lock();
  52.         out.erase(out.begin());
  53.         globalMutex.unlock();
  54.         ++count;
  55.     }
  56. }
  57.  
  58. int main()
  59. {
  60.     enum { NumOfThread = 2 };
  61.  
  62.     std::vector<std::thread> threads;
  63.     std::queue<std::pair<unsigned, std::string> > in;
  64.     std::map<unsigned, std::string> out;
  65.     volatile unsigned count = 0;
  66.     std::thread outputThread(Output, std::ref(out), std::ref(count));
  67.  
  68.     for (int i = NumOfThread; i --> 0; )
  69.         threads.push_back(std::thread(std::bind(Encode, std::ref(in), std::ref(out))));
  70.  
  71.     std::string str;
  72.     while (std::cin >> str && str != "END")
  73.     {
  74.         in.push(make_pair(count++, std::move(str)));
  75.         condDoTask.notify_one();
  76.     }
  77.     isMissionComplete = true;
  78.     condDoTask.notify_all();
  79.  
  80.     outputThread.join();
  81.     std::for_each(threads.begin(), threads.end(), std::mem_fn(&std::thread::join));
  82. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement