From 4acb19a62b1f2415589b4c2d31d8f4f8a959eaf1 Mon Sep 17 00:00:00 2001 From: kyleskyguo <32405872+kyleskyguo@users.noreply.github.com> Date: Tue, 20 May 2025 09:17:46 +0800 Subject: [PATCH] hw05 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 通过利用多线程技术及MUTEX完成安全读写 --- main.cpp | 94 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 58 insertions(+), 36 deletions(-) diff --git a/main.cpp b/main.cpp index f4ecab8..1dafed7 100644 --- a/main.cpp +++ b/main.cpp @@ -6,44 +6,63 @@ #include #include #include +#include +#include +#include +#include - -struct User { +struct User +{ std::string password; std::string school; std::string phone; }; std::map users; -std::map has_login; // 换成 std::chrono::seconds 之类的 +std::map has_login; // 换成 std::chrono::seconds 之类的 +std::mutex users_mtx; +std::mutex login_mtx; // 作业要求1:把这些函数变成多线程安全的 // 提示:能正确利用 shared_mutex 加分,用 lock_guard 系列加分 -std::string do_register(std::string username, std::string password, std::string school, std::string phone) { +std::string do_register(std::string username, std::string password, std::string school, std::string phone) +{ User user = {password, school, phone}; + std::lock_guard lock(users_mtx); if (users.emplace(username, user).second) return "注册成功"; else return "用户名已被注册"; } -std::string do_login(std::string username, std::string password) { +std::string do_login(std::string username, std::string password) +{ // 作业要求2:把这个登录计时器改成基于 chrono 的 - long now = time(NULL); // C 语言当前时间 - if (has_login.find(username) != has_login.end()) { - int sec = now - has_login.at(username); // C 语言算时间差 - return std::to_string(sec) + "秒内登录过"; + // long now = time(NULL); // C 语言当前时间 + auto now = std::chrono::steady_clock::now(); + { + std::lock_guard lock(login_mtx); + if (has_login.find(username) != has_login.end()) + { + // int sec = now - has_login.at(username); // C 语言算时间差 + int sec = std::chrono::duration_cast(now - has_login.at(username)).count(); + return std::to_string(sec) + "秒内登录过"; + } } has_login[username] = now; - - if (users.find(username) == users.end()) - return "用户名错误"; - if (users.at(username).password != password) - return "密码错误"; + { + std::lock_guard lock(users_mtx); + if (users.find(username) == users.end()) + return "用户名错误"; + if (users.at(username).password != password) + return "密码错误"; + } return "登录成功"; } -std::string do_queryuser(std::string username) { +std::string do_queryuser(std::string username) +{ + std::lock_guard lock(users_mtx); auto &user = users.at(username); std::stringstream ss; ss << "用户名: " << username << std::endl; @@ -52,38 +71,41 @@ std::string do_queryuser(std::string username) { return ss.str(); } - -struct ThreadPool { - void create(std::function start) { +struct ThreadPool +{ + std::vector> task; + void create(std::function start) + { // 作业要求3:如何让这个线程保持在后台执行不要退出? // 提示:改成 async 和 future 且用法正确也可以加分 - std::thread thr(start); + task.emplace_back(std::async(std::launch::async, std::move(start))); } + void wait(){for(auto &f:task)f.get();} }; ThreadPool tpool; - -namespace test { // 测试用例?出水用力! -std::string username[] = {"张心欣", "王鑫磊", "彭于斌", "胡原名"}; -std::string password[] = {"hellojob", "anti-job42", "cihou233", "reCihou_!"}; -std::string school[] = {"九百八十五大鞋", "浙江大鞋", "剑桥大鞋", "麻绳理工鞋院"}; -std::string phone[] = {"110", "119", "120", "12315"}; +namespace test +{ // 测试用例?出水用力! + std::string username[] = {"张心欣", "王鑫磊", "彭于斌", "胡原名"}; + std::string password[] = {"hellojob", "anti-job42", "cihou233", "reCihou_!"}; + std::string school[] = {"九百八十五大鞋", "浙江大鞋", "剑桥大鞋", "麻绳理工鞋院"}; + std::string phone[] = {"110", "119", "120", "12315"}; } -int main() { - for (int i = 0; i < 262144; i++) { - tpool.create([&] { - std::cout << do_register(test::username[rand() % 4], test::password[rand() % 4], test::school[rand() % 4], test::phone[rand() % 4]) << std::endl; - }); - tpool.create([&] { - std::cout << do_login(test::username[rand() % 4], test::password[rand() % 4]) << std::endl; - }); - tpool.create([&] { - std::cout << do_queryuser(test::username[rand() % 4]) << std::endl; - }); +int main() +{ + for (int i = 0; i < 262144; i++) + { + tpool.create([&] + { std::cout << do_register(test::username[rand() % 4], test::password[rand() % 4], test::school[rand() % 4], test::phone[rand() % 4]) << std::endl; }); + tpool.create([&] + { std::cout << do_login(test::username[rand() % 4], test::password[rand() % 4]) << std::endl; }); + tpool.create([&] + { std::cout << do_queryuser(test::username[rand() % 4]) << std::endl; }); } // 作业要求4:等待 tpool 中所有线程都结束后再退出 + tpool.wait(); return 0; }