Skip to content

Instantly share code, notes, and snippets.

@robosina
Last active February 21, 2022 07:06
Show Gist options
  • Save robosina/54ec2bc12c75d1031c12a168091fc973 to your computer and use it in GitHub Desktop.
Save robosina/54ec2bc12c75d1031c12a168091fc973 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <future>
#include <string>
#include <mutex>
#include <iomanip>
using namespace std::chrono_literals;
/// global variables
auto constexpr workerThreadDuration = 1000ms;
auto constexpr numberOfRepeats = 10;
auto constexpr numberOfRequest = 2050; // number of requests(for each request, a worker thread is created)
std::mutex mapLock;
std::mutex printLock;
struct stringLock {
std::mutex stringMutex;
std::mutex OwnerMutex;
std::condition_variable condition;
bool ready = false;
bool processed = false;
};
std::unordered_map<std::string, stringLock> getObjectMapLock;
static std::string getTime();
static int printColored(const std::string &message, const std::string &time);
std::string getObjectWorker(const std::string &str) {
std::unique_lock<std::mutex> lock(getObjectMapLock[str].stringMutex);
getObjectMapLock[str].condition.wait(lock, [&] { return getObjectMapLock[str].ready; });
{
std::lock_guard<std::mutex> plock(printLock);
printColored(str, getTime());
}
std::this_thread::sleep_for(std::chrono::milliseconds(workerThreadDuration));
return str;
}
std::string get_requests(const std::string &req) {
//lock the map
{
std::lock_guard<std::mutex> lock(mapLock);
//check if the request is already in the map
if (getObjectMapLock.find(req) == getObjectMapLock.end()) {
//create a new stringLock
getObjectMapLock.emplace(std::piecewise_construct,
std::forward_as_tuple(req),
std::forward_as_tuple());
}
}
{
std::lock_guard<std::mutex> globLock(getObjectMapLock[req].OwnerMutex);
std::future<std::string> f = std::async(std::launch::async,getObjectWorker, std::ref(req));
{
std::lock_guard<std::mutex> lock(getObjectMapLock[req].stringMutex);
getObjectMapLock[req].ready = true;
}
getObjectMapLock[req].condition.notify_one();
return f.get();
}
}
int main() {
for (int j = 0; j < numberOfRepeats; j++) {
std::vector<std::string> requests = {"request1", "request2", "request3", "request4", "request5", "request6",
"request7", "request8", "request9", "request10"};
std::vector<std::future<std::string>> futures;
for (auto i = 0; i < numberOfRequest; i++) {
futures.push_back(std::async(get_requests, requests[rand() % 10]));
}
for (auto &f: futures) {
f.get();
}
std::cout << "All requests are done" << std::endl;
std::cout << "starting new iteration" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(500ms));
}
}
std::string getTime() {
// date in yyyy/MM/dd hh:mm:ss format
time_t now = time(0);
struct tm tstruct;
char buf[80];
tstruct = *localtime(&now);
strftime(buf, sizeof(buf), "%X", &tstruct);
return buf;
}
int printColored(const std::string &message, const std::string &time) {
int second = std::stoi(time.substr(6, 2));
int color = second % 2 == 0 ? 32 : 33;
auto extractNumber = [](const std::string &str) {
return std::stoi(str.substr(7, str.size() - 1));
};
auto num = extractNumber(message);
//create an star in the num position(previous is " ")
std::string str = "";
for (int i = 0; i < num; i++) {
str += " ";
}
str += "**" + std::to_string(num) + "**";
std::cout << "\033[" << color << "m" << "[" << time << "]" << std::left << std::setw(6) << message << str
<< "\033[0m"
<< std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment