#include <iostream>
#include <thread>
#include <vector>
#include <mutex>
#include <chrono>
#include <queue>
class LockedQueue {
std::queue<int> queue_;
mutable std::mutex mutex_;
public:
LockedQueue() = default;
// these don't have to be deleted, but you'd have to decide whether or
// not each operation needed to invoke a lock, and in the case of operator=
// you have two mutexes to contend with.
LockedQueue(const LockedQueue&) = delete;
LockedQueue(LockedQueue&&) = delete;
LockedQueue& operator=(const LockedQueue&) = delete;
LockedQueue& operator=(LockedQueue&&) = delete;
void push(int value) {
std::lock_guard<std::mutex> lock(mutex_);
queue_.push(value);
}
int pop() {
std::lock_guard<std::mutex> lock(mutex_);
int value = queue_.front();
queue_.pop();
return value;
}
bool empty() const {
std::lock_guard<std::mutex> lock(mutex_);
return queue_.empty();
}
};
void func(LockedQueue& work, LockedQueue& results);
int main()
{
LockedQueue work, results;
std::vector<std::thread> threads;
for (int i = 0; i < 4; i++)
{
work.push(i);
threads.emplace_back(func, std::ref(work), std::ref(results));
}
for (auto& thread : threads)
thread.join();
while (!results.empty()) {
int i = results.pop();
std::cout << i;
}
}
void func(LockedQueue& work, LockedQueue& results)
{
int index = work.pop();
using namespace std::chrono_literals;
std::this_thread::sleep_for(1s);
results.push(index);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dGhyZWFkPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8bXV0ZXg+CiNpbmNsdWRlIDxjaHJvbm8+CiNpbmNsdWRlIDxxdWV1ZT4KCmNsYXNzIExvY2tlZFF1ZXVlIHsKCXN0ZDo6cXVldWU8aW50PiBxdWV1ZV87CgltdXRhYmxlIHN0ZDo6bXV0ZXggbXV0ZXhfOwpwdWJsaWM6CglMb2NrZWRRdWV1ZSgpID0gZGVmYXVsdDsKCQoJLy8gdGhlc2UgZG9uJ3QgaGF2ZSB0byBiZSBkZWxldGVkLCBidXQgeW91J2QgaGF2ZSB0byBkZWNpZGUgd2hldGhlciBvcgoJLy8gbm90IGVhY2ggb3BlcmF0aW9uIG5lZWRlZCB0byBpbnZva2UgYSBsb2NrLCBhbmQgaW4gdGhlIGNhc2Ugb2Ygb3BlcmF0b3I9CgkvLyB5b3UgaGF2ZSB0d28gbXV0ZXhlcyB0byBjb250ZW5kIHdpdGguCglMb2NrZWRRdWV1ZShjb25zdCBMb2NrZWRRdWV1ZSYpID0gZGVsZXRlOwoJTG9ja2VkUXVldWUoTG9ja2VkUXVldWUmJikgPSBkZWxldGU7CglMb2NrZWRRdWV1ZSYgb3BlcmF0b3I9KGNvbnN0IExvY2tlZFF1ZXVlJikgPSBkZWxldGU7CglMb2NrZWRRdWV1ZSYgb3BlcmF0b3I9KExvY2tlZFF1ZXVlJiYpID0gZGVsZXRlOwoKCXZvaWQgcHVzaChpbnQgdmFsdWUpIHsKCQlzdGQ6OmxvY2tfZ3VhcmQ8c3RkOjptdXRleD4gbG9jayhtdXRleF8pOwoJCXF1ZXVlXy5wdXNoKHZhbHVlKTsKCX0KCWludCBwb3AoKSB7CgkJc3RkOjpsb2NrX2d1YXJkPHN0ZDo6bXV0ZXg+IGxvY2sobXV0ZXhfKTsKCQlpbnQgdmFsdWUgPSBxdWV1ZV8uZnJvbnQoKTsKCQlxdWV1ZV8ucG9wKCk7CgkJcmV0dXJuIHZhbHVlOwoJfQoJYm9vbCBlbXB0eSgpIGNvbnN0IHsKCQlzdGQ6OmxvY2tfZ3VhcmQ8c3RkOjptdXRleD4gbG9jayhtdXRleF8pOwoJCXJldHVybiBxdWV1ZV8uZW1wdHkoKTsKCX0KfTsKCnZvaWQgZnVuYyhMb2NrZWRRdWV1ZSYgd29yaywgTG9ja2VkUXVldWUmIHJlc3VsdHMpOwoKaW50IG1haW4oKQp7CglMb2NrZWRRdWV1ZSB3b3JrLCByZXN1bHRzOwogICAgc3RkOjp2ZWN0b3I8c3RkOjp0aHJlYWQ+IHRocmVhZHM7CgogICAgZm9yIChpbnQgaSA9IDA7IGkgPCA0OyBpKyspCiAgICB7CiAgICAJd29yay5wdXNoKGkpOwogICAgICAgIHRocmVhZHMuZW1wbGFjZV9iYWNrKGZ1bmMsIHN0ZDo6cmVmKHdvcmspLCBzdGQ6OnJlZihyZXN1bHRzKSk7CiAgICB9CgogICAgZm9yIChhdXRvJiB0aHJlYWQgOiB0aHJlYWRzKQogICAgICAgIHRocmVhZC5qb2luKCk7CgoJd2hpbGUgKCFyZXN1bHRzLmVtcHR5KCkpIHsKCQlpbnQgaSA9IHJlc3VsdHMucG9wKCk7CgkJc3RkOjpjb3V0IDw8IGk7Cgl9Cn0KCnZvaWQgZnVuYyhMb2NrZWRRdWV1ZSYgd29yaywgTG9ja2VkUXVldWUmIHJlc3VsdHMpCnsKCWludCBpbmRleCA9IHdvcmsucG9wKCk7Cgl1c2luZyBuYW1lc3BhY2Ugc3RkOjpjaHJvbm9fbGl0ZXJhbHM7CglzdGQ6OnRoaXNfdGhyZWFkOjpzbGVlcF9mb3IoMXMpOwogICAgcmVzdWx0cy5wdXNoKGluZGV4KTsKfQ==