Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <thread>
- #include <vector>
- #include <queue>
- #include <algorithm>
- #include <map>
- #include <string>
- #include <condition_variable>
- #include <mutex>
- std::condition_variable condDoTask, condOutput;
- std::mutex globalMutex, encodeMutex, outputMutex;
- volatile bool isMissionComplete = false;
- void Encode(std::queue<std::pair<unsigned, std::string>>& in, std::map<unsigned, std::string>& out)
- {
- while (true)
- {
- std::unique_lock<std::mutex> lock(encodeMutex);
- condDoTask.wait(lock, [&in] { return !in.empty() || isMissionComplete; });
- if (isMissionComplete)
- break;
- globalMutex.lock();
- std::pair<unsigned, std::string> deal(std::move(in.front()));
- globalMutex.unlock();
- in.pop();
- ///////// DO YOUR TASK HERE //////////
- std::for_each(deal.second.begin(), deal.second.end(),
- [] (char& c) { c = std::isupper(c) ? std::tolower(c) : std::toupper(c); } );
- ///////// DO YOUR TASK HERE //////////
- globalMutex.lock();
- out.insert(std::move(deal));
- globalMutex.unlock();
- condOutput.notify_all();
- }
- condOutput.notify_all();
- }
- void Output(std::map<unsigned, std::string>& out, const volatile unsigned& total)
- {
- unsigned count = 0;
- while (true)
- {
- std::unique_lock<std::mutex> lock(outputMutex);
- condOutput.wait(lock,
- [&out, count, &total] { return (!out.empty() && count == out.begin()->first) || ( isMissionComplete && count == total); });
- if (isMissionComplete && count == total)
- break;
- std::cout << out.begin()->second << std::endl;
- globalMutex.lock();
- out.erase(out.begin());
- globalMutex.unlock();
- ++count;
- }
- }
- int main()
- {
- enum { NumOfThread = 2 };
- std::vector<std::thread> threads;
- std::queue<std::pair<unsigned, std::string> > in;
- std::map<unsigned, std::string> out;
- volatile unsigned count = 0;
- std::thread outputThread(Output, std::ref(out), std::ref(count));
- for (int i = NumOfThread; i --> 0; )
- threads.push_back(std::thread(std::bind(Encode, std::ref(in), std::ref(out))));
- std::string str;
- while (std::cin >> str && str != "END")
- {
- in.push(make_pair(count++, std::move(str)));
- condDoTask.notify_one();
- }
- isMissionComplete = true;
- condDoTask.notify_all();
- outputThread.join();
- std::for_each(threads.begin(), threads.end(), std::mem_fn(&std::thread::join));
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement